2
摘要:使用Writer monad時,我希望能夠在不失去狀態的情況下在mappend
的2個不同版本之間切換。在Writer monad中交換`mappend`
我用兩個布爾標誌來跟蹤一些狀態:
data Flags = F Bool Bool
現在我定義了兩個Monoid
情況下它的方式不同,他們結合旗幟mappend
:
newtype XFlags = XF Flags
instance Monoid XFlags where
mempty = XF (F True False)
(XF (F s0 c0)) `mappend` (XF (F s1 c1)) = XF (F (s0 && s1)
(c0 || c1 || not (s0 || s1)))
newtype SFlags = SF Flags
instance Monoid SFlags where
mempty = SF (F True False)
(SF (F s0 c0)) `mappend` (SF (F s1 c1)) = SF (F (s0 && s1) (c0 || c1))
現在我可以有2 Writer monads不同國旗處理:
type XInt = WriterT XFlags Identity Int
type SInt = WriterT SFlags Identity Int
現在我可以有這樣的操作:
xplus :: XInt -> XInt -> XInt
xplus = liftM2 (+)
splus :: SInt -> SInt -> SInt
splus = liftM2 (+)
我們,我想建立一個像表達式:
foo = splus (return 1) (xplus (return 2) (return 3))
要做到這一點,我需要能夠在兩者之間轉換,而不會丟失任何標誌和最好不用展開monad(使用runWriter
)。這部分我沒有弄清楚。它看起來有點像我可以嘗試使用monad變壓器來嵌套編寫器,但我不確定它是否可以直接在這裏使用。我會欣賞一些關於實現這樣的最佳方式的指導。
你爲什麼不打開monad? – luqui
理想情況下,我想monad跟蹤整個計算樹。後來我可以使用不同的Monoid來建立跟蹤或做一些其他分析。隱含地解開它會打破這個(我認爲)。完全公開:上面的例子在Haskell中,但我實際上是在Coq中實現它:) – krokodil
然而,最終你要解決這個問題,你需要一種方法來將來自'xplus'的'XFlags'與來自'SFlags' 'splus'。 – Cactus