2012-01-04 18 views
10

Validations in Haskell में दावा किया गया था कि Writer का उपयोग सही-सहयोगी concatenation की गारंटी देता है। हालांकि, यह उदाहरण अन्यथा दिखाना प्रतीत होता है। सही जवाब क्या है?क्या लेखक मोनाड सही सहयोगी concatenation की गारंटी देता है?

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

+1। –

+0

दिलचस्प बात यह है कि यदि आप 'replicateM_' को 'replicateM'' से प्रतिस्थापित करते हैं, तो आउटपुट 'हैलो" ++ ("वर्ल्ड" ++ ("वर्ल्ड" ++ "" ++ "") ++ "") ++ " ! " – pat

+3

यह 'अनुक्रम' और 'अनुक्रम_' के बीच का अंतर है:' अनुक्रम = फ़ोल्डर (लिफ्टएम 2 (:)) (वापसी [])' लेकिन 'sequence_ = foldr (>>) (वापसी())'; पूर्व अधिक बाध्य उत्पन्न करता है क्योंकि यह परिणाम के साथ चीजें करता है। – ehird

उत्तर

7

हाँ, यह वास्तव में गलत है। source code से:

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

... 

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

तो mappend रों की श्रृंखला (>>=) रों की श्रृंखला का आईना होगा।

1

Writer [a] सही-सहयोगी concatenation की गारंटी नहीं देता है, लेकिन आप Writer (Endo [a]) के साथ सही दाएं सहयोगी concatenation प्राप्त कर सकते हैं। 'शोप्रैक' का उपयोग करने और कार्यान्वित करने के सरल उदाहरण के लिए

संबंधित मुद्दे