说我有一些Monadic类型
data Example a = CheckIt {unwrap :: a}
instance Functor Example where
fmap f (CheckIt x) = CheckIt (f x)
instance Applicative Example where
pure = CheckIt
CheckIt f <*> CheckIt x = CheckIt (f x)
instance Monad (Example) where
return = CheckIt
e@(CheckIt a) >>= f = f a
我有一个函数,根据一些输入返回[a]
:
fetchList :: b -> [Int]
fetchList _ = [1,2,3,4]
和一个返回IO [a]的函数(从实际实现中简化):
basicIoWrap :: [a] -> IO [a]
basicIoWrap x = return x
我想运行这个IO,然后从中提取一个例子[a]:
以下不起作用:
foo :: b -> Example [a]
foo val = (basicIoWrap (fetchList val)) >>= \list -> return list
抱怨不同的monad类型
Couldn't match type ‘IO’ with ‘Example’
Expected type: Example [a]
Actual type: IO [Int]
所以我明白这正是Monad变形金刚的用法,但我真的在努力弄清楚如何在上下文中应用它们。说我有一个变压器:
newtype ExampleT m a = ExampleT {runExampleT :: m (Example a)}
我将签名改为 foo :: b - &gt;例T(IO [a])
我不清楚函数体会是什么样子,以及我最终如何从中提取一个例子[a]?不会runExampleT ExampleT (IO [a])
给IO [Example a]
,因此只会在未来的道路上引发多Monad问题吗?
答案 0 :(得分:2)
你永远无法安全逃脱&#34;来自IO
,但如果您的某个类型的值Example (IO [a])
且Example
至少为Traversable
,那么您可以将其转换为IO (Example [a])
sequence
函数。使用此方法,您可以将foo
函数编写为:
foo :: b -> IO (Example [a])
foo = sequence . return . basicIoWrap . fetchList
由于您必须已在IO
monad中工作才能使用basicIoWrap
,因此您可以访问Example [a]
。例如:
do input <- getLine
(Example as) <- foo input
mapM_ print as