haskellmonadsabstraction# Continuation abstraction

In a general exercise about concurrency based on this article.

We have:

```
-- a is the result type on which after we continue
type Continuation a = a-> Action
type ContinuationPseudoMonad a = Continuation a -> Action
-- pseudoMonad because it will need Concurrent wrapper Monad:
-- so as to define bind operation and return operation on it
data Concurrent a = Concurrent (ContinuationPseudoMonad a)
```

so `Concurrent a`

is a monad we have to implement with its two mandatory laws, return and bind.

Unfortunatly, I find no adequate words for defining more precisely the ContinuationPseudoMonad thing... and if I lack words, I lack abstraction in my mind.

How would you call it ?

Is there a word meaning `Continuation a -> Action`

instead of my awkward meaningless `ContinuationPseudoMonad`

?

Action being:

```
data Action = Atom (IO Action)
| Fork Action Action
| Stop
```

Solution

It is evident `Concurrent a`

is the same as `Cont Action a`

where `Cont`

is the continuation monad. Here's a simple explanation for continuations:

- Consider the function
`f :: a -> b`

for some arbitrary types`a`

and`b`

. We want to convert this function into continuation passing style. How do we do so? - Let's say we have a continuation
`k :: b -> r`

which takes the return value of`f`

as an input and itself returns a value of an arbitrary type`r`

. Following this, we can convert`f`

to CPS. - Let
`g :: a -> (b -> r) -> r`

be the CPS version function of`f`

. Note that it takes an additional argument (i.e. the continuation`k`

) and returns the result of`k`

applied to its output`b`

.

Let's take a practical example where `f`

is the predicate function `odd :: Int -> Bool`

:

```
odd :: Int -> Bool
odd n = n `mod` 2 == 1
```

Here's the same function written in continuation passing style:

```
odd' :: Int -> (Bool -> r) -> r
odd' n k = k (n `mod` 2 == 1)
```

The `(Bool -> r) -> r`

part can be abstracted out as the continuation monad:

```
data Cont r a = Cont { runCont :: (a -> r) -> r }
odd' :: Int -> Cont r Bool
odd' n = return (n `mod` 2 == 1)
instance Monad (Cont r) where
return a = Cont (\k -> k a)
m >>= f = Cont (\k -> runCont m (\a -> runCont (f a) k))
```

Notice that the type of the continuation `k`

is `Bool -> r`

for some arbitrary type `r`

. Hence, the continuation `k`

could be any function which takes a `Bool`

as an argument. For example:

```
cont :: Bool -> IO ()
cont = print
main :: IO ()
main = odd' 21 cont
```

However, in the case of `Concurrent`

this `r`

is not arbitrary. It has been specialized to `Action`

. In fact, we can define `Concurrent`

as a type synonym for `Cont Action`

as follows:

```
type Concurrent = Cont Action
```

Now, we don't need to implement the `Monad`

instance for `Concurrent`

because it's the same as the `Monad`

instance for `Cont r`

as defined above.

```
runConcurrent :: Concurrent a -> ContinuationPseudoMonad a
runConcurrent (Concurrent g) = g
instance Monad Concurrent where
return a = Concurrent (\k -> k a)
m >>= f = Concurrent (\k -> runConcurrent m (\a -> runConcurrent (f a) k))
```

Note that nowhere in the definition of `instance Monad Concurrent`

have we made use of `Action`

. That's because `Concurrent = Cont Action`

and the monad instance of `Cont r`

uses `r`

transparently.

- Haskell fails to infer the return type of a monad after using the sequence operator
- Does extracting values from a multiple Value return in Haskell invoke the function more than once?
- Why do I get "Unexpected reply type" from notify-send when using this Haskell notification server?
- Don't understand notation of morphisms in Monoid definition
- Foldln in haskell
- Is this property of a functor stronger than a monad?
- How to Instantiate a Custom Data Type with Record Syntax and Multiple Constructors
- How do I make a minimal working example for the a DBus server?
- Is it safe to downgrade Haskell stack version?
- Haskell, list of natural number
- unfamiliar syntax in Haskell / Clash function type signature
- foldM with monad State does not type check
- Why does my Runge-Kutta implementation oscillate to 0?
- How do I get the desired behavior in my TCP server?
- Why does the Haskell PVP describe new functions as non-breaking?
- How do I correctly use toLower in Haskell?
- How can I write a notification server in Haskell?
- Every Lens' is a Traversal'... how?
- How do I crate a value of type a{sv} for a call to org.freedesktop.Notifications.Notify via DBus?
- Web Scraping With Haskell
- Double exclamation marks in Haskell
- Haskell Servant POST FormUrlEncoded for (Vector String) field
- Confusion about list types in Haskell
- Idiomatic way to define new vs persisted types in Haskell
- Why does Cabal, unlike GHC, not automatically enable GeneralizedNewtypeDeriving if I explicitly enabled DerivingStrategies?
- What is the proper way of wrapping an Int (not a general type) in another type if type safety is the only motive?
- Parsing inside `between` with Megaparsec
- takeWhile implementation in JavaScript - Looking for better ideas
- How to setup MINGW environment variables for Haskell language server in vscode?
- mysql-haskell no invoke of Right case of try function