[Haskell-beginners] newbie: Monad, equivalent notation using Control.Monad.guard

Brent Yorgey byorgey at seas.upenn.edu
Mon Oct 17 18:22:21 CEST 2011


On Mon, Oct 17, 2011 at 04:18:05PM +0100, Hugo Ferreira wrote:
> Hello,
> 
> I came across the following code:
> 
> ngrams'' :: Int -> [a] -> [[a]]
> ngrams'' n l = do
>   t <- Data.List.tails l
>   l <- [take n t]
>   Control.Monad.guard (length l == n)
>   return l
> 
> and tried to use the ">>=" operator in order
> to figure out how Monads work. I came up with:
> 
> test l =
>    (Data.List.tails l)
>    >>= (\t -> [take 2 t])
>    >>= (\l -> if (length l == 2) then [l] else [])
> 
> Questions:
> 1. How can I use Control.Monad.guard directly in "test l"

test l =
    (Data.List.tails l)
    >>= \t -> [take 2 t]
    >>= \l -> Control.Monad.guard (length l == 2)
    >>  return l

The rule is that 

  x <- foo

desugars to

  foo >>= \x -> ...

and

  blah

desugars to

  blah >> ...

One thing that might have been tripping you up is your extra
parentheses around the lambda expressions.  If you have

  >>= (\l -> ...)
  >>  foo...

the l does not scope over foo... so you cannot mention it.  Instead
what you want is

  >>= \l -> ...
  >>  foo...

so the lambda expression is actually   \l -> ... >> foo..., that is,
it includes *everything* after the \l -> ... and not just the stuff on
that line.

> 2. Related issue: how can create a List monad so that I
>    can input "l" argument of "test l" directly?

I don't understand this question.  Can you give an example of what you
are trying to do?

-Brent



More information about the Beginners mailing list