FreeT/ProgramT創建的monad變換器可以有類似於mtl的機制嗎?Monad堆棧滲透類與免費/操作Monad變壓器?
我對歷史的理解如下。曾幾何時,monad變壓器被髮明出來。然後人們開始將monad變壓器堆疊在一起,然後發現在任何地方插入lift
都很煩人。然後有幾個人發明了monad類,以便我們可以例如ask :: m r
in any monad m
such as MonadReader r m
。這是可能通過使每個單子類滲透每一個單子轉換,像
(Monoid w, MonadState s m) => MonadState s (WriterT w m)
MonadWriter w m => MonadWriter w (StateT s m)
你需要對這樣的實例聲明的每對單子變壓器,所以當有ñ單子變形金剛有ñ^2費用。然而,這並不是一個大問題,因爲人們大多會使用預定義的單子,很少創建自己的單子。到目前爲止,我明白這個故事,還有一些細節,例如在以下Q &答:
Avoiding lift with Monad Transformers
然後我的問題是與新自由單子http://hackage.haskell.org/package/free和運營單子http://hackage.haskell.org/package/operational。它們允許我們編寫我們自己的DSL並將其用作monad,只需將語言定義爲某種代數data
類型(Operational甚至不需要Functor
實例)。好消息是我們可以免費獲得monads和monad變形金剛;那麼monad課程呢?壞消息是,「我們很少定義我們自己的monad變壓器」的假設不再成立。
作爲試圖理解這個問題,我做了兩個ProgramT
s,使他們互相滲透;
https://github.com/nushio3/practice/blob/master/operational/exe-src/test-05.hs
的operational
包不支持單子類,所以我又實現minioperational
,並修改了它的工作,因爲我需要; https://github.com/nushio3/minioperational
不過,我需要專門的實例聲明
instance (Monad m, Operational ILang m) => Operational ILang (ProgramT SLang m) where
因爲以下形式的一般性聲明導致不可判定的實例。
instance (Monad m, Operational f m) => Operational f (ProgramT g m) where
我的問題是,我們怎樣才能使它更容易讓我們的業務單子互相滲透。或者,我希望能夠滲透任何行動不便的單身漢。
我也想知道正確的技術術語,滲透 :)
謝謝你,彼得。在你的幫助下,我明白瞭如何使用''(* - > *)''結合兩個類型構造函數。 https://github.com/nushio3/practice/blob/master/operational/exe-src/test-06.hs 編寫可組合的口譯員也一樣簡單: https://github.com/nushio3/practice/ blob/master/operational/exe-src/test-07.hs 我們甚至可以以'OverlappingInstances'爲代價編寫兩種以上的語言。 https://github.com/nushio3/practice/blob/master/operational/exe-src/test-08.hs – nushio