[Haskell-beginners] Pointfree expeiments
Paul Sargent
psarge at gmail.com
Thu Nov 25 05:55:39 EST 2010
Thanks Stephen,
On 25 Nov 2010, at 09:12, Stephen Tetley wrote:
> On 25 November 2010 01:44, Paul Sargent <psarge at gmail.com> 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
More information about the Beginners
mailing list