Haskell newtype语法

时间:2013-07-11 17:52:29

标签: haskell newtype

请帮助我理解以下定义:

newtype Writer w a = Writer { runWriter :: (a,w) } 

instance (Monoid w) => Monad (Writer w) where 
    return a             = Writer (a,mempty) 
    (Writer (a,w)) >>= f = let (a',w') = runWriter $ f a in Writer (a',w `mappend` w')

为什么runWriter被声明为

runWriter :: (a,w)

当它的实际类型是:

runWriter :: Writer w a -> (a, w)

一旦我尝试使用ghci,我意识到这必须是一些隐含的参数,因为必须确定类型“a”,但这里究竟发生了什么?

2 个答案:

答案 0 :(得分:8)

因为runWriterWriter上的记录字段访问者。它实际上几乎相当于

runWriter (Writer x) = x

Haskell只有记录提供

  1. 因为这种访问代码很常见所以语法更方便
  2. 功能更新的能力
  3. 其他一些扩展
  4. 例如

    someWriter{runWriter = (new, values)} -- Returns a new Writer.
    

    如果它有所帮助,可以将它想象成最粗糙的“功能性吸气剂”。对于1字段,这可能看起来并不十分重要,您可以始终模式匹配,但是当您有5个字段时,记录+功能更新非常有用。有关更深入的解释,请参阅LYAH

答案 1 :(得分:0)

另一种看待它的方法:你可以想象像这样定义2元组(如果特殊的(,)语法不是一个特殊的内置语法)

data  (,)  a b   =   (,)  { fst :: a, snd :: b }

然后fstsnd会表现正常:

fst :: (a,b) -> a
fst (x,y) = x

(例如newtype适用于只有一个值字段的类型。对于包含多个字段的类型,需要data。)