我正在尝试编写一个程序,该程序将 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-GenTGenT m 是一个 MonadIO 实例,只要 m 是。

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

似乎可以工作。

关于haskell - 如何结合 Arbitrary 和 IO monad?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47664913/

10-10 08:14