Haskell: monadic takeWhile?

前端 未结 5 947
一整个雨季
一整个雨季 2020-12-30 07:33

I have some functions written in C that I call from Haskell. These functions return IO (CInt). Sometimes I want to run all of the functions regardless of what

5条回答
  •  独厮守ぢ
    2020-12-30 08:07

    You can use the one from the "List" package.

    import Control.Monad.ListT (ListT)
    import Data.List.Class (execute, fromList, joinM, takeWhile)
    import Prelude hiding (takeWhile)
    
    f x = print x >> return x
    main =
      execute . takeWhile (< 4) .
      joinM $ fmap f (fromList [0..5] :: ListT IO Int)
    
    • fromList [0..5] creates a monadic list containing 0..5 which performs no monadic actions
    • fmap f to that list results in a ListT IO (IO Int) which still performs no monadic actions, just contains ones.
    • joinM turns that into a ListT IO Int. every contained action would get executed when the item is consumed and its result will be the value in the list.
    • takeWhile is generalized for any List. Both [] and "Monad m => ListT m" are instances of List.
    • execute consumes the monadic list, executing all its actions.
    • In case you are interested in the results you can use "toList :: List m => m a -> ItemM m [a]" ("ItemM (ListT IO)" is IO). so in this case it's "toList :: ListT IO a -> IO [a]". Better yet you can keep using higher-order functions such as scanl, etc to process the monadic list as it is being executed.

提交回复
热议问题