有关MonadWriter的新手问题:
monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n")
为什么在类型签名中先出现
String
,然后是Int
,而3003
明显是一个Int
,而"log 1\n"
则是一个String
呢?这可能非常琐碎,但我希望理解。有关MonadWriter的新手问题:
monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n")
String
,然后是Int
,而3003
明显是一个Int
,而"log 1\n"
则是一个String
呢?这可能非常琐碎,但我希望理解。没有特定的原因将结果 (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中曲线救国。