14

リストモナド変換子を使用する必要があります。可換ではないため、ListT IOfromには潜在的な問題があることを読みました。そのため、 ListTが正しく実行されていることを確認しています。しかし、予期しない動作が発生しています。Control.Monad.ListIO

この簡単なテストを考えてみましょう。

test = runListT $ do
  x <- liftList [1..3]
  liftIO $ print x
  y <- liftList [6..8]
  liftIO $ print (x,y)

Control.Monad.Listの使用:

Main> test
1
(1,6)
(1,7)
(1,8)
2
(2,6)
(2,7)
(2,8)
3
(3,6)
(3,7)
(3,8)
[(),(),(),(),(),(),(),(),()]

「ListTdoneright」の使用:

Main> test
1
(1,6)

これは「ListTが正しく行われた」という問題ですか、それとも間違って使用しているだけですか?望ましい代替案はありますか?

ありがとう!

4

1 に答える 1

8

彼らが言うので、これは作者の側で内包的かもしれません

これにより、リストの各要素に独自の副作用が発生し、リストのこの要素が実際に検査された場合にのみ「実行」されます。

でも、よくわかりません。とにかく、この関数を使用してリスト全体をシーケンスすることができます。

runAll_ :: (Monad m) => ListT m a -> m ()
runAll_ (ListT m) = runAll_' m where
    runAll_' m = do
        mm <- m
        case mm of
             MNil          -> return ()
             _ `MCons` mxs -> runAll_' mxs

そして、runAllリストを返すアナロジーは簡単に作成できるはずです。

main = runAll_ $ do
    x <- liftList [1..3]
    liftIO $ print x
    y <- liftList [6..8]
    liftIO $ print (x,y)

1
(1,6)
(1,7)
(1,8)
2
(2,6)
(2,7)
(2,8)
3
(3,6)
(3,7)
(3,8)
于 2012-03-15T19:28:43.003 に答える