Haskell MonadWriter 类型签名:

4

有关MonadWriter的新手问题:

monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n") 

为什么在类型签名中先出现String,然后是Int,而3003明显是一个Int,而"log 1\n"则是一个String呢?这可能非常琐碎,但我希望理解。
1个回答

7

没有特定的原因将结果 (3003) 放在输出 ("log 1\n") 前面作为 writer 函数的参数。我猜这个顺序是为了对应 WriterT 的内部表示

newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }

(对于Writer来说,m是身份元素。)
然而,在Writer的类型签名中,参数的顺序是有关系的。例如,如果我们看一下Functor类型类及其成员,参数的顺序如下所示:
fmap :: (a -> b) -> f a -> f b

通过使用Writer String(或一般情况下的Writer result)替换f,可以实现以下功能:

fmap :: (a -> b) -> Writer result a -> Writer result b

这正是参数正确的顺序。如果交换它们,实现Functor会变得很困难(除非采用一些诡计)。对于所有需要多个参数的类型/函数,唯一可将其用作单参数类型/函数的方法是通过改变最后一个参数而不是其他参数。查看相关问题以了解类似问题的讨论: 在Haskell中切换实例声明的参数顺序 在Haskell中曲线救国

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接