
As a Haskell neophyte, one of the things I find confusing is the way that the usual list functions (map, fold, ++, etc.) often cannot be used directly with monadic lists (m [a] or [m a]) but seem to require special purpose functions like ap, mapM etc. I get the idea of separating pure and impure code but am constantly frustrated by the fact that stuff that would be easy outside a monad seems to get more difficult inside, especially list manipulation. As a result I tend to write ugly recursive list functions that would be more appropriate with Python, say. I suspect that things are not quite as difficult as they appear, however, but cannot find any tutorials on monadic list manipulation. Any suggestions for resources in that area? Kevin

2010/7/26 Kevin Jardine
As a Haskell neophyte, one of the things I find confusing is the way that the usual list functions (map, fold, ++, etc.) often cannot be used directly with monadic lists (m [a] or [m a]) but seem to require special purpose functions like ap, mapM etc.
Note that this is not specific to lists. For instance you can't directly use (+) :: Int -> Int -> Int with values of type m Int
I get the idea of separating pure and impure code but am constantly frustrated by the fact that stuff that would be easy outside a monad seems to get more difficult inside, especially list manipulation. As a result I tend to write ugly recursive list functions that would be more appropriate with Python, say.
I suspect that things are not quite as difficult as they appear, however, but cannot find any tutorials on monadic list manipulation.
Any suggestions for resources in that area?
You may look at applicative style programming, with Control.Applicative. Also, just like with IO, maybe restructuring the code to separate monadic code would help. Cheers, Thu

On Jul 26, 3:00 pm, Vo Minh Thu
Also, just like with IO, maybe restructuring the code to separate monadic code would help.
The specific monad I am dealing with carries state around inside it. I could revert to a pure system in many cases by simply passing the state as a parameter but then that defeats the point of the monad and clutters up my function calls. Also, in other cases, I am using a module that defines its own monads and have no choice but to use them. I think I would prefer a style of programming where monads are equal citizens to pure function calls. There are various hints that such a style of programming is possible but as I say, I have not found any clear tutorials on it.

2010/7/26 Kevin Jardine
On Jul 26, 3:00 pm, Vo Minh Thu
wrote: Also, just like with IO, maybe restructuring the code to separate monadic code would help.
The specific monad I am dealing with carries state around inside it.
I could revert to a pure system in many cases by simply passing the state as a parameter but then that defeats the point of the monad and clutters up my function calls.
Also, in other cases, I am using a module that defines its own monads and have no choice but to use them.
I think I would prefer a style of programming where monads are equal citizens to pure function calls. There are various hints that such a style of programming is possible but as I say, I have not found any clear tutorials on it.
Maybe you missed the part of my answer hinting to applicative style? LYAH has a chapter about it[0]. There are other resources about it. I believe there is a well-known paper that introduced the idea and is quite readable. RWH uses it with Parsec. [0] http://learnyouahaskell.com/functors-applicative-functors-and-monoids

On Jul 26, 3:19 pm, Vo Minh Thu
Maybe you missed the part of my answer hinting to applicative style?
No, I saw that but as I mentioned, I am looking for a tutorial. The source code alone means little to me.
LYAH has a chapter about it[0].
Thanks for the pointer. I have read LYAH before (perhaps an earlier version) and did not notice that chapter. I'll take a look at it. Kevin

Can you post an example of your code? mapM and map are actually for pretty distinct purposes. If you find yourself wanting to map over a pure list in monadic code, you should really look at applicative style, e.g.: import Control.Applicative data Struct = .... deriving (Read) readStructs :: IO [Struct] readStructs = map read . lines <$> getContents It lets you apply a pure function (or a composition of pure functions) to a monadic value. Note that the above is exactly equivalent to: readStructs = do contents <- getContents return . map read . lines $ contents On Monday Jul 26, 2010, at 9:13 AM, Kevin Jardine wrote:
On Jul 26, 3:00 pm, Vo Minh Thu
wrote: Also, just like with IO, maybe restructuring the code to separate monadic code would help.
The specific monad I am dealing with carries state around inside it.
I could revert to a pure system in many cases by simply passing the state as a parameter but then that defeats the point of the monad and clutters up my function calls.
Also, in other cases, I am using a module that defines its own monads and have no choice but to use them.
I think I would prefer a style of programming where monads are equal citizens to pure function calls. There are various hints that such a style of programming is possible but as I say, I have not found any clear tutorials on it. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Jul 26, 3:26 pm, Bill Atkins
Can you post an example of your code?
Without getting into the complexities, one simple example is a fold where the step function returns results in a monad. I have taken to replacing the fold in that case with a recursive function, which surely is the wrong approach. I think foldM might do the job but am unsure. But as I said, that is just an example. I keep wanting to apply the usual list tools but find that they do not work inside a monad. I find myself wishing that f (m [a]) just automatically returned m f([a]) without me needing to do anything but I expect that there are reasons why that is not a good idea. Kevin

On Jul 26, 3:49 pm, Kevin Jardine
I find myself wishing that f (m [a]) just automatically returned m f([a]) without me needing to do anything but I expect that there are reasons why that is not a good idea.
Or is there a monadic list module where f(m [a]) = m f ([a]) ? It occurs to me that Haskell provides the tools to construct such a module (I think) so probably one exists? Kevin

The answer is still applicative. :) On Monday Jul 26, 2010, at 10:06 AM, Kevin Jardine wrote:
On Jul 26, 3:49 pm, Kevin Jardine
wrote: I find myself wishing that f (m [a]) just automatically returned m f([a]) without me needing to do anything but I expect that there are reasons why that is not a good idea.
Or is there a monadic list module where f(m [a]) = m f ([a]) ?
It occurs to me that Haskell provides the tools to construct such a module (I think) so probably one exists?
Kevin _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Kevin Jardine wrote:
But as I said, that is just an example. I keep wanting to apply the usual list tools but find that they do not work inside a monad. I find myself wishing that f (m [a]) just automatically returned m f([a])
Are you looking for these? import Data.Traversable as T T.sequence :: (T.Traversable t, Monad m) => t (m a) -> m (t a) T.mapM :: (T.Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) -- N.B. T.mapM ~ (T.sequence . fmap)
without me needing to do anything but I expect that there are reasons why that is not a good idea.
Not all functors can be distributed over arbitrary monads, so "not a good idea" is more like "not always possible" or "here be dragons" (fluffy, intriguing, and pretty dragons to be sure; but probably deeper than the answer you were looking for). In addition to Applicative, the Traversable and Foldable classes should be key tools in your toolbox. They take a number of functions typically restricted to lists and generalize them to different functors, often with Applicatives or Monads involved. The Typeclassopedia should have more on them. -- Live well, ~wren

Looks interesting.
I've also come across Data.List.Class:
http://hackage.haskell.org/packages/archive/generator/0.5.1/doc/html/Data-Li...
Has anyone used that?
Kevin
On Jul 27, 6:02 pm, wren ng thornton
Kevin Jardine wrote:
But as I said, that is just an example. I keep wanting to apply the usual list tools but find that they do not work inside a monad. I find myself wishing that f (m [a]) just automatically returned m f([a])
Are you looking for these?
import Data.Traversable as T T.sequence :: (T.Traversable t, Monad m) => t (m a) -> m (t a) T.mapM :: (T.Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) -- N.B. T.mapM ~ (T.sequence . fmap)
without me needing to do anything but I expect that there are reasons why that is not a good idea.
Not all functors can be distributed over arbitrary monads, so "not a good idea" is more like "not always possible" or "here be dragons" (fluffy, intriguing, and pretty dragons to be sure; but probably deeper than the answer you were looking for).
In addition to Applicative, the Traversable and Foldable classes should be key tools in your toolbox. They take a number of functions typically restricted to lists and generalize them to different functors, often with Applicatives or Monads involved. The Typeclassopedia should have more on them.
-- Live well, ~wren _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

On 07/26/2010 08:13 AM, Kevin Jardine wrote:
On Jul 26, 3:00 pm, Vo Minh Thu
wrote: Also, just like with IO, maybe restructuring the code to separate monadic code would help.
The specific monad I am dealing with carries state around inside it.
I could revert to a pure system in many cases by simply passing the state as a parameter but then that defeats the point of the monad and clutters up my function calls.
Also, in other cases, I am using a module that defines its own monads and have no choice but to use them.
I think I would prefer a style of programming where monads are equal citizens to pure function calls. There are various hints that such a style of programming is possible but as I say, I have not found any clear tutorials on it.
It's not much of a tutorial, but Software Tools in Haskell[1][2] apparently uses monads more than some people are comfortable with, including stacks of monad transformers in the later chapters. [1] http://www.crsr.net/Programming_Languages/SoftwareTools/index.html [2] Heck, the later chapters are only marginally readable. -- Tommy M. McGuire mcguire@crsr.net

2010/7/26 Kevin Jardine
I suspect that things are not quite as difficult as they appear, however, but cannot find any tutorials on monadic list manipulation.
I'd suggest that you get as many pure values as possible from impure world, apply to them easy to use pure functions (list processing, etc) to get the desired result and, only then, put result back into impure world. It is even more exciting because you can create and combine impure actions as pure values.
participants (6)
-
Bill Atkins
-
Kevin Jardine
-
Serguey Zefirov
-
Tommy M. McGuire
-
Vo Minh Thu
-
wren ng thornton