
Thanks Stephen, On 25 Nov 2010, at 09:12, Stephen Tetley wrote:
On 25 November 2010 01:44, Paul Sargent
wrote: [SNIP] I'm aware that 'ap' is related the liftM, but what is this monad, and why are we working in a monad at all?
...and surely this isn't the same as the original code as we now have a different type signature?_______________________________________________
Its the Reader monad.
[...]
Pointfree is presumably introducing it because it can't find elementary definitions that are only functional types [...]
In one stroke it is a use of the 'w' combinator:
-- | W combinator - warbler - elementary duplicator. w :: (r1 -> r1 -> ans) -> r1 -> ans w f x = f x x
Monadic ap for the Reader monad corresponds to the Starling 's' combinator:
starling :: (r1 -> a -> ans) -> (r1 -> a) -> r1 -> ans starling f g x = f x (g x)
The Starling and Warbler combinators make perfect sense to me. I'm still trying to see how ap in the Reader Monad is equivalent to Starling. I think this is exposing some holes in my Haskell knowledge, so I'm using it as a learning exercise. We use them in the same way, and we're saying they're equivalent: let f x = starling (+) id let g x = ap (+) id Yet, they have quite different type signatures. starling :: (r1 -> a -> ans) -> (r1 -> a) -> r1 -> ans ap :: (Monad m) => m (a -> b) -> m a -> m b So, my first question is what makes haskell choose the Reader monad in this case? Secondly, (+) is a function of two arguments, and id a function of one. This binds naturally with starling, but not apparently with ap. Apparently ap wants a single argument function within a monad as it's first argument, so to me (+) shouldn't satisfy. I suspect the answer to this has something to do with my first question. Digging a little deeper, I decided to look at the definition of ap: ap = liftM2 id 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) } liftM2 makes sense to me, but again we seem to have a mismatch of types. liftM2 wants a two argument function for it's first argument, but ap provides id. I'm finding myself tumbling further and further down the rabbit hole. Paul