Haskell MonadWriter类型签名

Mad*_*ote 4 monads haskell writer type-signature

关于MonadWriter的Noob问题:

monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n") 
Run Code Online (Sandbox Code Playgroud)

为什么它String首先出现在typeig中Int,然后3003是第二个,而显然是Int一会儿"log 1\n"是一个String。我知道微不足道,但我想了解。

Kot*_*lar 7

没有特别的理由将结果(3003)放在第一位,将输出("log 1\n")放在第二位的参数上writer。我想,顺序被选择为对应于的内部表示形式WriterT

newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
Run Code Online (Sandbox Code Playgroud)

(对于Writerm是身份)。

但是,在for的类型签名中Writer,参数的顺序很重要。例如,如果我们查看Functor带有成员的typeclass

fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

从而有可能替代Writer String(或通常是Writer resultf并获得

fmap :: (a -> b) -> Writer result a -> Writer result b
Run Code Online (Sandbox Code Playgroud)

这正是参数的正确顺序。交换它们将使实现成为Functor不可能(没有任何技巧)。

对于具有多个参数的所有类型/函数,这都是正确的:将它们用作一个参数类型/函数的唯一方法是更改​​最后一个参数,而不是其他参数。

请参阅讨论类似问题的相关问题:

在Haskell中切换实例声明的参数顺序

在Haskell中乱序处理