
Whoa... how on earth does this work? How does it interpret the sections as Reader monads?
That's a job for the reader monad.
Lambda Fu, form 53 - silent reader of truth
import Control.Monad import Control.Monad.Reader
filter (liftM2 (&&) (< 0.5) (> -0.5)) xs
Regards, apfelmus

Am Montag 19 Oktober 2009 17:24:12 schrieb Jordan Cooper:
Whoa... how on earth does this work? How does it interpret the sections as Reader monads?
liftM2 (&&) :: (Monad m) => m Bool -> m Bool -> m Bool So for (liftM2 (&&) (< 0.5) (> -0.5)) to be well typed, we must have (< 0.5) :: m Bool for some Monad m (same for (> -0.5)). Now (< 0.5) :: Fractional a => a -> Bool, hence m must be ((->) a) for some a in the Fractional class. Reader r a is just (r -> a) wrapped in a newtype, so (r -> a) 'is' the reader monad. To use it, we must import Control.Monad for liftM2 and some module which brings the instance Monad ((->) r) into scope. That could be Control.Monad.Instances or, appropriately, Control.Monad.Reader.
That's a job for the reader monad.
Lambda Fu, form 53 - silent reader of truth
import Control.Monad import Control.Monad.Reader
filter (liftM2 (&&) (< 0.5) (> -0.5)) xs
Regards, apfelmus

This one had me puzzled too - so did a traced through the program below. Please make sure your viewing window is at least this wide: <----------------------------------------------------------------> It was more helpful to think of this as using the ((->) r) instance of Monad. It is defined in ./libraries/base/Control/Monad/Instances.hs in your GHC source as:
instance Monad ((->) r) where return = const f >>= k = \ r -> k (f r) r
And const just returns its first argument like: const 1 3 => 1 const "hello" "world" => "hello" And liftM2 is defined in ./libraries/base/Control/Monad.hs as :
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
So a trace of the program goes like this:
(liftM2 (&&) (< 0.5) (> -0.5))
=> do {x1 <- (< 0.5);
x2 <- (> -0.5);
return ((&&) x1 x2)}
=> (< 0.5) >>= \x1
(> -0.5) >>= \x2
return ((&&) x1 x2)
=> \r ->(\x1 ->
(> -0.5) >>= \x2
return ((&&) x1 x2))
((< 0.5) r)
r
=> \r -> (return (> -0.5) >>= \x2
return ((&&) ((< 0.5) r) x2))
r
=> \r -> (\r' -> (\x2 ->
return ((&&) (const (< 0.5) r) x2))
((> -0.5) r')
r')
r
=> \r -> (\r' -> (return ((&&) ((< 0.5) r) ((> -0.5) r'))) r') r
=> \r -> (\r' -> (const ((&&) ((< 0.5) r) ((> -0.5) r'))) r') r
=> \r -> (\r' -> ((&&) ((< 0.5) r) ((> -0.5) r'))) r
=> \r -> (\r' -> ((r < 0.5) && (r' > -0.5))) r
hope this helps,
-deech
On Mon, Oct 19, 2009 at 10:24 AM, Jordan Cooper
Whoa... how on earth does this work? How does it interpret the sections as Reader monads?
That's a job for the reader monad.
Lambda Fu, form 53 - silent reader of truth
import Control.Monad import Control.Monad.Reader
filter (liftM2 (&&) (< 0.5) (> -0.5)) xs
Regards, apfelmus
Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

There was a mistake in the trace, please ignore the previous one and look at
this. Again your viewing window should be this wide:
<----------------------------------------------------------------->
(liftM2 (&&) (< 0.5) (> -0.5))
=> do {x1 <- (< 0.5);
x2 <- (> -0.5);
return ((&&) x1 x2)}
=> (< 0.5) >>= \x1
(> -0.5) >>= \x2
return ((&&) x1 x2)
=> \r ->(\x1 ->
(> -0.5) >>= \x2
return ((&&) x1 x2))
((< 0.5) r)
r
=> \r -> ((> -0.5) >>= \x2
return ((&&) ((< 0.5) r) x2))
r
=> \r -> (\r' -> (\x2 ->
return ((&&) (const (< 0.5) r) x2))
((> -0.5) r')
r')
r
=> \r -> (\r' -> (return ((&&) ((< 0.5) r) ((> -0.5) r'))) r') r
=> \r -> (\r' -> (const ((&&) ((< 0.5) r) ((> -0.5) r'))) r') r
=> \r -> (\r' -> ((&&) ((< 0.5) r) ((> -0.5) r'))) r
=> \r -> (\r' -> ((r < 0.5) && (r' > -0.5))) r
On Mon, Oct 19, 2009 at 11:42 AM, aditya siram
This one had me puzzled too - so did a traced through the program below. Please make sure your viewing window is at least this wide: <---------------------------------------------------------------->
It was more helpful to think of this as using the ((->) r) instance of Monad. It is defined in ./libraries/base/Control/Monad/Instances.hs in your GHC source as:
instance Monad ((->) r) where return = const f >>= k = \ r -> k (f r) r
And const just returns its first argument like: const 1 3 => 1 const "hello" "world" => "hello"
And liftM2 is defined in ./libraries/base/Control/Monad.hs as :
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
So a trace of the program goes like this:
(liftM2 (&&) (< 0.5) (> -0.5)) => do {x1 <- (< 0.5); x2 <- (> -0.5); return ((&&) x1 x2)}
=> (< 0.5) >>= \x1 (> -0.5) >>= \x2 return ((&&) x1 x2)
=> \r ->(\x1 -> (> -0.5) >>= \x2 return ((&&) x1 x2)) ((< 0.5) r) r
=> \r -> (return (> -0.5) >>= \x2 return ((&&) ((< 0.5) r) x2)) r
=> \r -> (\r' -> (\x2 -> return ((&&) (const (< 0.5) r) x2)) ((> -0.5) r') r') r => \r -> (\r' -> (return ((&&) ((< 0.5) r) ((> -0.5) r'))) r') r => \r -> (\r' -> (const ((&&) ((< 0.5) r) ((> -0.5) r'))) r') r => \r -> (\r' -> ((&&) ((< 0.5) r) ((> -0.5) r'))) r => \r -> (\r' -> ((r < 0.5) && (r' > -0.5))) r
hope this helps, -deech
On Mon, Oct 19, 2009 at 10:24 AM, Jordan Cooper
wrote: Whoa... how on earth does this work? How does it interpret the sections as Reader monads?
That's a job for the reader monad.
Lambda Fu, form 53 - silent reader of truth
import Control.Monad import Control.Monad.Reader
filter (liftM2 (&&) (< 0.5) (> -0.5)) xs
Regards, apfelmus
Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (3)
-
aditya siram
-
Daniel Fischer
-
Jordan Cooper