Reputation: 4319
I'm trying to do a bit of programming and I can't get into monads. I've advanced a bit with IO functions, but now I'm definitely lost...
I've got a XML string that was loaded from the network (so it's "stored" in IO String
). Because of this, I need a do
block to load to common String.
foo :: IO String -> Nothing
foo xmlio = do
xmlio <- xml
-- do some magic
I've already implemented another function that takes pure string and returns pure XML element. It does a bit more, but let's simplify that as it's not important for this question.
import Text.XML.Light
import Text.XML.Light.Input
toxml :: String -> Maybe Element
toxml s = parseXMLDoc s
Now I tried to combine these two to accept an IO String and to return an "IO Element".
toxmlio :: IO String -> ??? Maybe Element
toxmlio s = do
pures <- s
let toReturn = parseXMLDoc s
return s
The return function's type is (according to ghci) :
let foo = "<foo>bar</foo>"
:t return (parseXMLDoc foo)
>> return (parseXMLDoc foo) :: Monad m => m (Maybe Element)
But if I change the header of my function to
toxmlio :: IO String -> Monad (Maybe Element)
toxmlio s = do
pures <- s
let toReturn = parseXMLDoc s
return s
I get a compilation error
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)
Does anyone have any idea how to solve this issue? Or am I completely lost and haskell does this another way? Thank you for your answer.
Upvotes: 0
Views: 630
Reputation: 144206
It looks like you want:
toxmlio :: IO String -> IO (Maybe Element)
toxmlio s = do
pures <- s
let toReturn = parseXMLDoc pures
return toReturn
however you can use liftM
:
toxmlio :: IO String -> IO (Maybe Element)
toxmlio = liftM parseXMLDoc
You could make it even more general, since liftM
does not depend on a particular monad type:
toxmlio :: Monad m => m String -> m (Maybe Element)
toxmlio = liftM parseXMLDoc
Upvotes: 3