【问题标题】:Does Writer Monad guarantee right associative concatenation?Writer Monad 是否保证右关联连接?
【发布时间】:2012-02-02 15:34:44
【问题描述】:

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" ++ "") ++ "!"

【问题讨论】:

  • +1 是使用和实现showsPrec 的简单示例。
  • 有趣的是,如果将replicateM_ 替换为replicateM,则输出变为"Hello" ++ ("World" ++ ("World" ++ "" ++ "") ++ "") ++ "!"
  • 这是sequencesequence_的区别:sequence = foldr (liftM2 (:)) (return [])但是sequence_ = foldr (>>) (return ());前者生成更多绑定,因为它对结果进行处理。
  • 无论如何,>> 应该是关联的。但我不是一元律师。
  • @JoeyAdams:确实;如果 w 遵循 Monoid 定律,Writer w 将遵循 Monad 定律。但非右关联mappends 通常效率低下。

标签: haskell monads writer


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    是的,这确实是不真实的。来自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)
    

    所以mappends 的链将镜像(&gt;&gt;=)s 的链。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-22
      • 2014-04-03
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      相关资源
      最近更新 更多