Haskell monad返回类型

时间:2013-05-14 21:50:25

标签: haskell io monads

我正在尝试做一些编程,但我无法进入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会这样做吗?谢谢你的回答。

1 个答案:

答案 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