
Hello, I have a function that returns its value in a monad, and I'd like to use that value in a function that returns an arrow, but I cannot figure out how to do that. The monad in this case is CouchMonad and the arrow is ArrowXml, but I guess that doesn't really matter. For example, the function that returns its value in a monad: toXNode :: String -> CouchMonad XNode and a function that returns an arrow: processReplacement :: (ArrowXml a) => String -> String -> a XmlTree XmlTree In processReplacement I'd like to get a value from toXNode function, take it out from the monad and use the plain XNode value. Were it all simply CouchMonad, it would be something like this: processReplacement elementId docId = do node <- toXNode docId setNode node `when` idMatches elementId But this is an arrow, so I need something different. I've read quite a few arrow articles and tutorials, but couldn't yet grasp how to do this and what is involved. Any ideas or pointers to examples? Thanks! BR, Jarno

Hi Jarno A cursory look at the CouchMonad says it is build upon the IO monad so you won't be able to safely extract values out of it. This suggests that you should "run" HXT functions within the CouchMonad monad. The HXT library has various run_ functions - runIOLA, runSt, ... - to run a computation and produce a value. I don't know the HXT library, so don't know which particular run function to use, but a viable construction might look like one of these two: processReplacement elementId docId state0 = do node <- toXNode docId let ans = runSt (setNode node `when` idMatches elementId) state0 return ans Or maybe runIOLA: processReplacement elementId docId = do node <- toXNode docId ans <- runIOLA (setNode node `when` idMatches elementId) return ans Best wishes Stephen

Hi Stephen,
A cursory look at the CouchMonad says it is build upon the IO monad so you won't be able to safely extract values out of it. This suggests that you should "run" HXT functions within the CouchMonad monad.
Right, that's pretty much what I was already doing, but I was thinking about a too complex solution. I was thinking more along the lines of using CouchMonad functions inside HXT arrow functions and getting a CouchMonad value out of my HXT arrow composition. That lead me thinking about transforming CouchMonad to a (Kleisli) arrow, but there the water is getting too deep for me and I'm not even sure if that's the right (or possible) direction. But your reply helped me to see an easier way.
The HXT library has various run_ functions - runIOLA, runSt, ... - to run a computation and produce a value. I don't know the HXT library, so don't know which particular run function to use, but a viable construction might look like one of these two:
Currently I'm using runX from Text.XML.HXT.Arrow.XmlIOStateArrow. The processReplacement is actually a part of a more complex arrow composition, and I was hoping I could somehow use CouchMonad functions deep inside the arrow composition and get the arrow machinery to propagate the CouchMonad value "up" and out from a run_ function.
processReplacement elementId docId = do node <- toXNode docId ans <- runIOLA (setNode node `when` idMatches elementId) return ans
This worked out nicely. Somehow I had missed that (in this case) I can just as well do the CouchMonad stuff outside the arrow composition, extract the value out of the monad and pass it to the arrow function, so that I don't need to have any monad stuff inside the arrow functions. I'm still left wondering what if the input to a monad function came from the output of an arrow so that I couldn't do the monad operations outside the arrow composition, but fortunately I don't have such a case yet :-) Thanks! Regards, Jarno
participants (2)
-
Jarno Antikainen
-
Stephen Tetley