Writer Monad是否保证正确的关联连接?

时间:2012-01-04 18:18:32

标签: haskell monads writer

Validations in Haskell中声称使用Writer保证了右关联连接。但是,这个例子似乎表明不是这样。什么是正确的答案?

{-# LANGUAGE OverloadedStrings #-}

import Control.Monad.Writer
import Data.String

data TM = TMempty
        | TMappend TM TM
        | TMfromString String

instance IsString TM where
  fromString = TMfromString

instance Monoid TM where
  mempty  = TMempty
  mappend = TMappend

instance Show TM where
  showsPrec d TMempty = showString "\"\""
  showsPrec d (TMfromString s) = showString $ show s
  showsPrec d (TMappend a b) = showParen (d > 0) $
    showsPrec 1 a .
    showString " ++ " .
    showsPrec 0 b

theWriter :: Writer TM ()
theWriter = do
  tell "Hello"
  replicateM_ 2 $ tell "World"
  tell "!"

main = print $ execWriter theWriter

产地:

"Hello" ++ ("World" ++ "World" ++ "") ++ "!"

2 个答案:

答案 0 :(得分:7)

是的,这确实是不真实的。来自source code

m >>= k  = WriterT $ do
    ~(a, w)  <- runWriterT m
    ~(b, w') <- runWriterT (k a)
    return (b, w `mappend` w')

...

-- | @'tell' w@ is an action that produces the output @w@.
tell :: (Monoid w, Monad m) => w -> WriterT w m ()
tell w = WriterT $ return ((), w)

因此mappend s的链将反映(>>=) s的链。

答案 1 :(得分:1)

Writer [a]不保证权利关联连接,但您可以通过Writer (Endo [a])获得保证的右关联连接。