[Haskell-beginners] newbie: Monad, equivalent notation using Control.Monad.guard
Hugo Ferreira
hmf at inescporto.pt
Tue Oct 18 14:07:57 CEST 2011
On 10/18/2011 11:52 AM, Brent Yorgey wrote:
> On Tue, Oct 18, 2011 at 10:52:57AM +0100, Hugo Ferreira wrote:
>> Hello,
>>
>> On 10/17/2011 05:22 PM, Brent Yorgey wrote:
>>> 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>> ...
>>>
>>
>> Ok, I was not aware of the>>.
>>
>>> 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.
>>>
>>
>> Hmmm. Still cannot wrap my mind around this B-(.
>>
>> [[1],[2],[3]]>>= \l -> func1 l>>= \m -> func2 m
>>
>> \l will hold each of the 3 elements of initial list
>> these are concatenated with the results of func1
>> results in a new list
>>
>> \m will have each element in the new list
>> these are concatenated with the results of func2
>> results in a last list
>>
>> is equal to ?
>>
>> (([[1],[2],[3]]>>= \l -> func1 l)>>= \m -> func2 m)
>
> Yes, your description is correct, and yes, these are equal. (Although
> the first is often more efficient.) They are required to be equal by
> the monad laws. However, consider
>
> [[1],[2],[3]]>>= \l -> func1 l>>= \m -> func2 m l
>
> and
>
> (([[1],[2],[3]]>>= \l -> func1 l)>>= \m -> func2 m l)
>
> Notice that func2 now takes a second argument. There is not even a
> question of whether these are equal: the second does not even compile,
> because the final 'l' is not in scope. This is the point I was trying
> to make.
Aaaah. Got it.
Thanks,
Hugo F.
>
> -Brent
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
More information about the Beginners
mailing list