我正在尝试做一些编程,但我无法进入monad。我已经提高了IO功能,但现在我肯定迷失了......
我有一个从网络加载的XML字符串(所以它“存储”在IO String
中)。因此,我需要一个do
块来加载到常见的String。
foo :: IO String -> Nothing
foo xmlio = do
xmlio <- xml
-- do some magic
我已经实现了另一个采用纯字符串并返回纯XML元素的函数。它做了一点,但让我们简化一下,因为它对这个问题并不重要。
import Text.XML.Light
import Text.XML.Light.Input
toxml :: String -> Maybe Element
toxml s = parseXMLDoc s
现在我尝试将这两者结合起来接受IO字符串并返回“IO元素”。
toxmlio :: IO String -> ??? Maybe Element
toxmlio s = do
pures <- s
let toReturn = parseXMLDoc s
return s
返回函数的类型是(根据ghci):
let foo = "<foo>bar</foo>"
:t return (parseXMLDoc foo)
>> return (parseXMLDoc foo) :: Monad m => m (Maybe Element)
但是,如果我将我的函数的标题更改为
toxmlio :: IO String -> Monad (Maybe Element)
toxmlio s = do
pures <- s
let toReturn = parseXMLDoc s
return s
我收到编译错误
Kind mis-match
The first argument of `Monad' should have kind `* -> *',
but `Maybe Element' has kind `*'
In the type signature for `xmlio':
xmlio :: String -> Monad (Maybe Element)
有谁知道如何解决这个问题?或者我完全迷失了,而且haskell会这样做吗?谢谢你的回答。
答案 0 :(得分:3)
看起来你想要:
toxmlio :: IO String -> IO (Maybe Element)
toxmlio s = do
pures <- s
let toReturn = parseXMLDoc pures
return toReturn
但是您可以使用liftM
:
toxmlio :: IO String -> IO (Maybe Element)
toxmlio = liftM parseXMLDoc
你可以使它更加通用,因为liftM
不依赖于特定的monad类型:
toxmlio :: Monad m => m String -> m (Maybe Element)
toxmlio = liftM parseXMLDoc