https://github.com/robrix/freer-cofreer
freer monads and cofreer comonads.
https://github.com/robrix/freer-cofreer
comonads haskell monads
Last synced: 5 months ago
JSON representation
freer monads and cofreer comonads.
- Host: GitHub
- URL: https://github.com/robrix/freer-cofreer
- Owner: robrix
- License: bsd-3-clause
- Created: 2017-01-29T15:53:38.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2018-06-26T16:12:45.000Z (over 7 years ago)
- Last Synced: 2025-08-23T22:49:24.871Z (5 months ago)
- Topics: comonads, haskell, monads
- Language: Haskell
- Size: 86.9 KB
- Stars: 23
- Watchers: 5
- Forks: 1
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# freer-cofreer: freer monads and cofreer comonads.
This is an implementation of the Freer monad described by Oleg Kiselykov in _[Free and Freer Monads: Putting Monads Back in the Closet][Free and Freer]_, and the Cofreer comonad, defined by analogy with Freer.
`Freer` and `Cofreer` differentiate themselves from `Free` and `Cofree` by admitting `Functor` & `Monad`/`Comonad` instances even when the signature is not a `Functor`. This makes them particularly suitable for working with certain GADTs. For example:
```Haskell
data PromptF a where
Write :: String -> PromptF ()
Read :: PromptF String
type Prompt = Freer PromptF
write :: String -> Prompt ()
write s = Write s `Then` Return
read :: Prompt String
read = Read `Then` Return
greeting :: Prompt ()
greeting = do
write "Hi! What’s your name?\n"
name <- read
write $ "Pleased to meet you, " ++ name ++ "!"
runPrompt :: Prompt a -> IO a
runPrompt = iterFreer (\ yield instruction -> case instruction of
Write s -> putStrLn >>= yield
Read -> getLine >>= yield)
```
The constraints placed on the constructors of `PromptF` mean that it doesn’t admit a `Functor` instance, and thus is not very useful with `Free`. With `Freer`, you get `Functor`, `Applicative`, and `Monad` instances with `PromptF` “for free,” complete with the majority of the API defined in `Control.Monad.Free.Freer`.
[Free and Freer]: http://okmij.org/ftp/Computation/free-monad.html