Haskell新类型语法

Haskell新类型语法,haskell,newtype,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`

请帮助我理解以下定义:

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”,但这里到底发生了什么?

因为
runWriter
Writer
上的记录字段访问器。实际上几乎相当于

runWriter (Writer x) = x
哈斯克尔只是有记录要说

  • 更方便的语法,因为这种访问器代码非常常见
  • 功能更新的能力
  • 其他一些扩展
  • 乙二醇


    如果它有帮助的话,可以把它看作是一种最粗略的“功能性的getter”。对于1个字段来说,这似乎不太重要,您可以始终进行模式匹配,但是当您有5个字段时,记录+功能更新非常有用。请参阅以获得更深入的解释。

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

    然后,
    fst
    snd
    将正常工作:

    fst :: (a,b) -> a
    fst (x,y) = x
    
    newtype
    在您的示例中适用于只有一个值字段的类型。对于有多个字段的类型,需要使用
    data
    。)

    data  (,)  a b   =   (,)  { fst :: a, snd :: b }
    
    fst :: (a,b) -> a
    fst (x,y) = x