簡體   English   中英

如何組合任意和IO monad?

[英]How to combine Arbitrary and IO monads?

我正在嘗試編寫一個程序,該程序將由Arbitrary實例生成的數據列表寫入文件,並且我在組合ArbitraryIO monad時遇到問題。

我想要做的簡化版本如下所示。

main = do
  let n = 10
  list <- vector n
  writeFile "output.txt" (unlines $ show <$> list)

這會導致類型錯誤,因為writeFileIO monad與vectorGen monad不匹配。

TestCases.hs:31:3: error:
    • Couldn't match type ‘IO’ with ‘Test.QuickCheck.Gen.Gen’
      Expected type: Test.QuickCheck.Gen.Gen ()
        Actual type: IO ()
    • In a stmt of a 'do' block:
        writeFile "output.txt" (unlines $ show <$> list)
      In the expression:
        do { let n = 10;
             list <- vector n;
             writeFile "output.txt" (unlines $ show <$> list) }
      In an equation for ‘main’:
          main
            = do { let n = ...;
                   list <- vector n;
                   writeFile "output.txt" (unlines $ show <$> list) }

我嘗試使用liftIO來解決這種類型不匹配問題,但由於Gen缺少MonadIO實例,它似乎不起作用。

main = do
  let n = 10
  list <- vector n :: Gen [Integer]
  liftIO $ writeFile "output.txt" (unlines $ show <$> list)

給出了錯誤

TestCases.hs:32:3: error:
    • No instance for (MonadIO Gen) arising from a use of ‘liftIO’
    • In a stmt of a 'do' block:
        liftIO $ writeFile "output.txt" (unlines $ show <$> list)
      In the expression:
        do { let n = 10;
             list <- vector n :: Gen [Integer];
             liftIO $ writeFile "output.txt" (unlines $ show <$> list) }
      In an equation for ‘main’:
          main
            = do { let n = ...;
                   list <- vector n :: Gen [Integer];
                   liftIO $ writeFile "output.txt" (unlines $ show <$> list) }

如何將任意生成的列表打印到文件中?

正如Test.QuickCheck.Gen告訴你的那樣,你可以使用GenT QuickCheck-GenT GenT mMonadIO實例每當m是。

main = join . generate . runGenT $ do
  let n = 10
  list <- liftGen $ vector n
  liftIO $ writeFile "output.txt" (unlines $ show <$> list)

似乎很有效。

vector函數為您提供列表生成器,而不是特定列表:

vector :: Arbitrary a => Int -> Gen [a]

由於(>>=) :: Monad m => ma -> (a -> mb) -> mb ,它不會讓你離開Gen 但是generateTest.QuickCheck.Gen不特定值代適用於這種情況: generate :: Gen a -> IO a 所以generate (vector n) >>= writeFile "output.txt" . unlines . map show generate (vector n) >>= writeFile "output.txt" . unlines . map show generate (vector n) >>= writeFile "output.txt" . unlines . map show應該做你想要的(除了類型模糊:在你的例子中不清楚你的向量會產生Gen [a] ,所以也許添加類似(vector n :: Gen [Int])除非你的實際應用程序為類型推斷提供了足夠的上下文

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM