阅读LYAH ,我偶然发现了这段代码:
newtype Writer w a = Writer { runWriter :: (a, w) }
instance (Monoid w) => Monad (Writer w) where
return x = Writer (x, mempty)
(Writer (x,v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v')
在尝试理解第一行中的 Writer w
到底是什么时,我发现这不是一个完整的类型,而是一种带有 1 个参数的类型构造函数,例如 Maybe
表示可能是字符串
看起来不错,但是如果 Writer'
的初始类型是使用交换的类型参数定义的,如下所示:
newtype Writer' a w = Writer' { runWriter :: (a, w) }
现在可以实现 Monad 实例吗?类似这样,但实际上可以编译什么:
instance (Monoid w) => Monad (\* -> Writer' * monoid) where
\* -> Writer' * monoid
的思想与 Writer w
相同:
缺少一个类型参数的类型构造函数 - 这次是第一个。
最佳答案
这在 Haskell 中是不可能的,您需要的是类型级 lambda 函数,但该函数不存在。
您可以使用类型同义词来定义类型变量的重新排序:
type Writer'' a w = Writer' a w
但是您不能为部分应用的类型同义词提供类实例(即使使用 TypeSynonymInstances
扩展)。
我写了关于如何将类型级 lambda 添加到 GHC 的硕士学位论文:https://xnyhps.nl/~thijs/share/paper.pdf在类型类实例中使用而不牺牲类型推断。
关于haskell - 高阶多态性是否需要严格的参数顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35310208/