2014-01-28 27 views
16

在對this question的評論中,已經提到嵌套幾層FreeT變換器(每個具有不同的函子)可以用於與"Data types à la carte"方法類似的目的儘管兩種方法不是同構的,但它們使用副產品組合了函數本身。「單點數據類型」與嵌套FreeT變換器

我的問題是:區別在哪裏?有一種方法可以處理的情況,但不是另一種?他們是否承認不同的口譯員?

更新:這裏有一個嵌套FreeT變壓器的簡單例子。增強的計算與發出的日誌消息,並請求延遲的能力:

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 

(這個特殊的例子可能已經變得更加簡單使用Producer■從pipes包,它是一種特殊的免費單子變壓器。 )

+3

據我瞭解,這是Haskell社區正在進行的一場辯論。例如見Kiselyov,Sabry&Swords'[「可擴展效應:單向變壓器的替代方案」](http://www.cs.indiana.edu/~sabry/papers/exteff.pdf)(PDF),以及在[Lambda The Ultimate](http://lambda-the-ultimate.org/node/4786)和[/ r/haskell in Reddit]中進行的討論(http://www.reddit.com/r/haskell/)評論/ 1j9n5y/extensible_effects_an_alternative_to_monad /)。 –

+0

@LuisCasillas「可擴展效果」是否與嵌套的FreeT方法或「數據類型點菜」相對應? – danidiaz

+2

我相信它對應於「點菜式數據類型」,但我不是100%確定的。無論如何,如果我正在閱讀這個權利[emkett說Extensible Effects〜= Datatypesàla carte + open union](http://www.reddit.com/r/haskell/comments/1j9n5y/extensible_effects_an_alternative_to_monad/cbcwbsa)。 –

回答

5

我對自己對此的理解並不是100%自信的,所以如果有人注意到任何(公然)錯誤,請指出。

與可擴展的效果開始,Eff類型是基本同構於:

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

其中Union es a是由a參數化類型es列表的工會/總和類型。 Union與來自數據類型單點菜單的重複應用:+:同構。總結(!),Eff似乎是數據類型單點菜單的優化版本。

我們可以得出這樣的結論:文中描述的單變換器和可擴展效應之間的區別適用於此。特別是,自由單體變壓器疊層不能交錯效應,而數據類型單點/可擴展效應可以。