Reputation: 3144
I need to write the following function:
bind :: ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
Action is a type constructor that I defined. Trouble is when I try to implement it in the following way:
bind f g =
I do not know how to pass a value of type "a" to the function g. I am clueless regarding to get the value.
As a matter of fact this looks like some kind of transforming one function to another, but I also don't know how to achieve that.
What should I do to make this transformation possible?
Upvotes: 1
Views: 163
Reputation: 12715
This is the Cont monad bind. Without a newtype wrapper it looks like this:
bind :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> ((b -> r) -> r)
First, remove redundant brackets:
bind :: ((a -> r) -> r) -> (a -> (b -> r) -> r) -> (b -> r) -> r
Second, let b -> r = br
:
bind :: ((a -> r) -> r) -> (a -> br -> r) -> br -> r
Now you have
bind s f k = ?
where s :: (a -> r) -> r
, f :: a -> br -> r
and k :: br
.
And
flip f k :: a -> r
s (flip f k) :: r
so
bind :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> ((b -> r) -> r)
bind s f k = s (flip f k)
Or simply
bind s f = s . flip f
Or in pointfree
bind = (. flip) . (.)
Upvotes: 5
Reputation: 116139
Your monad is called the continuation monad Cont r a = ((a->r)->r)
(minus a newtype wrapper) where r = Action
in your case. But let's adventure a bit without looking at how that monad is defined...
Let's boldly start with:
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = (??? :: (b -> Action) -> Action)
So, let's start filling the ???
. We need to produce a function, so let's exploit a lambda for that:
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = \k :: (b -> Action) -> (??? :: Action)
Once having overcome that, we now need to craft an Action
. We have several functions in our hands returning that: f,g,k
, each requiring different args. This is a matter of trial-and-error. Let's guess... f
.
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = \k :: (b -> Action) -> f (??? :: a -> Action)
We again need a function: sprinkle more lambdas, more lambdas!
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = \k :: (b -> Action) -> f (\x :: a -> (??? :: Action))
Groan..., we need again to produce an Action
. Was what we did pointless? Are we looping in circles? No, we now have x :: a
in scope, so we now grew in power. Let's use g
now:
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = \k :: (b -> Action) -> f (\x :: a -> g (???1 : a) (???2 :: b -> Action))
Well, the first argument of g
is now trivial to find.
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = \k :: (b -> Action) -> f (\x :: a -> g x (???2 :: b -> Action))
More lambdas, more lambdas!
bind :: forall a b. ((a -> Action) -> Action) -> (a -> ((b -> Action) -> Action)) -> ((b -> Action) -> Action)
bind f g = \k :: (b -> Action) -> f (\x :: a -> g x (\y :: b -> (??? :: Action)))
Argh! Not another Action
to produce! But all is not lost, we grew in power: we now have both x::a
and y::b
at our call! We also never used k
... uhm....
To do:
???
.return
/unit function for the monad.Upvotes: 3