Haskell 独特的签名类型

Haskell MonadWriter type signature

关于 MonadWriter 的菜鸟问题:

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

为什么 String 在 typesig 中排在第一位,而 Int 其次,而 3003 显然是一个 Int"log 1\n" 是一个 String。 琐碎我知道,但我想明白。

writer 的参数中,没有特别的理由将结果 (3003) 放在第一位,将输出 ("log 1\n") 放在第二位。我想,选择的顺序对应于 internal representation of WriterT:

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

(对于Writerm是同一性)。

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

Functor 类型类
fmap :: (a -> b) -> f a -> f b

可以用Writer String(或者一般来说,Writer result)代替f并得到

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

这正是参数的正确顺序。交换它们将使实施 Functor 变得不可能(没有一些诡计)。

对于所有接受多个参数的 types/functions 都是如此:它们可以用作单参数 types/functions 的唯一方法是改变最后一个参数,而不是其他参数。

查看讨论类似问题的相关问题:

Switch order of arguments for instance declaration in Haskell

Currying out of order in Haskell