>>= implementation for Poor Man's Concurrency Monad
haskell, monads
Solution
The definition you are looking for reads something like
Concurrent h >>= k = Concurrent (\f -> h (\x -> runConcurrent (k x) f))
How did we get there? As always, we let the types do the work. :)
Let us first introduce a helper function:
runConcurrent :: Concurrent b -> (b -> Action) -> Action
runConcurrent (Concurrent h) = h
If you start out with the left-hand side of your definition
Concurrent h >>= k = ...
with `h :: (a -> Action) -> Action` and `k :: a -> Concurrent b`, then your goal is to replace `...` with an expression of type `Concurrent b`, isn't it?
How can we construct a value of type `Concurrent b`? One way is to apply our function `k`, but that won't work, because we don't have a suitable value of type `a` available as an argument. So, pretty much the only thing we can do is to apply the data constructor `Concurrent` which is of type `((b -> Action) -> Action) -> Concurrent b`.
That gives:
Concurrent h >>= k = Concurrent ...
Now we have to go and find us an expression of type `(b -> Action) -> Action` to supply as an argument for `Concurrent`. We know that expressions of function type can always be constructed through lambda-abstraction:
Concurrent h >>= k = Concurrent (\f -> ...)
This gives us `f :: b -> Action` and the obligation to replace `...` with an expresion of type `Action`. Using one of the `Action`-constructors directly would be cheating of course ;). To guarantee the genericity of `(>>=)` (more precisely, to make sure that we end up obeying the monad laws), we treat `Action` as if it's an abstract datatype. Then, the only way to produce an `Action`-value is to apply the function `h`:
Concurrent h >>= k = Concurrent (\f -> h ...)
Hence, next we need to supply `h` with an argument of type `a -> Action`. That is a function type again, so we throw in another lambda:
Concurrent h >>= k = Concurrent (\f -> h (\x -> ...))
Hence, we have `x :: a` and need to construct a body of type `Action`. What can we do with a value of type `a`? We can supply it to the function `k`. This gives us a value of type `Concurrent b`, which we can then pass to our helper function `runConcurrent`:
Concurrent h >>= k = Concurrent (\f -> h (\x -> runConcurrent (k x) ...))
This gives us a function of type `(b -> Action) -> Action` and supplying `f` as an argument does the trick:
Concurrent h >>= k = Concurrent (\f -> h (\x -> runConcurrent (k x) f))
Problem
Hi I am trying to implement the Poor Man's Concurrency Monad. Here is my code: ``` import Control.Monad data Concurrent a = Concurrent ((a -> Action) -> Action) data Action = Atom (IO Action) | Fork Action Action | Stop instance Monad Concurrent where (Concurrent ma) >>= f = Concurrent (\x -> ma(\y -> "Something return a Action")) return x = Concurrent (\c -> c x) ``` Here is my analysis: `x` has the type of `b`, `y` has the type of `a`, `f` has the type of `(a -> ((b ->Action) -> Action))`. In order to figure out "Something return a Action", I firstly calculate `(f y)`, which returns a type of `((b ->Action) -> Action)`. Then, how can use it with `x` to generate a Action?