Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Data types à la carte" vs. nested FreeT transformers

Tags:

haskell

monads

In the comments to this question, it has been mentioned that nesting several layers of FreeT transformers (each with a different functor) can serve a similar purpose to the "Data types à la carte" approach (that combines the functors themselves using coproducts) despite the two approaches not being isomorphic.

My question is: where does the difference lie? Are there cases that one approach can handle, but not the other? Do they admit different interpreters?

Update: Here's a simple example of nested FreeT transformers. Augmenting a computation with the ability to emit log messages and request delays:

import Data.Functor.Identity
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Trans.Free
import Control.Concurrent

type Delay = Int

type DelayT = FreeT ((,) Delay)

delay ::  Monad m => Delay -> DelayT m ()
delay t = liftF (t,()) 

type Message = String

type LogT = FreeT ((,) Message)

emitLog :: Monad m => Message -> LogT m ()
emitLog msg = liftF (msg,()) 

type Effected = DelayT (LogT Identity)

program :: Effected Char
program = lift (emitLog "foo") >> delay 1000 >> return 'c'

interpret :: Effected a -> IO a 
interpret =                          (iterT $ \(d,a)->threadDelay d >> a)  
            . hoistFreeT             (iterT $ \(m,a)->putStrLn m >> a) 
            . hoistFreeT (hoistFreeT (return . runIdentity))

main :: IO ()
main = interpret program >>= putChar  

(This particular example could have been made even simpler by using Producers from the pipes package, which are a particular kind of free monad transformers.)

like image 680
danidiaz Avatar asked Jan 28 '14 20:01

danidiaz


1 Answers

I'm not 100% confident in my own understanding of this, so if anyone notices anything (blatantly) wrong, please point it out.

Starting with Extensible Effects, the Eff type is basically isomorphic to:

data Eff :: [* -> *] -> * -> * where
    Pure :: a -> Eff es a
    Side :: Union es (Eff es a) -> Eff es a

where Union es a is a union/sum type of the list of types es parameterized by a. Union is isomorphic to repeated applications of :+: from Data Types a la Carte. To sum (!) it all up, Eff seems to be an optimized version of Data Types a la Carte.

We may conclude that the differences between monad transformers and extensible effects described in the paper apply here. In particular, free monad transformer stacks cannot interleave effects, while Data Types a la Carte/Extensible Effects can.

like image 71
YellPika Avatar answered Nov 05 '22 17:11

YellPika