【发布时间】:2014-12-12 22:41:24
【问题描述】:
我有以下代码:
class Coll c e where
map :: (e1 -> e2) -> c e1 -> c e2
merge :: (e -> e -> e) -> e -> c e -> e
sum :: (Num e) => c e -> e
sum = merge (+) 0
到目前为止一切顺利。但后来我有:
sumMap :: (Num e2) => (e1 -> e2) -> c e1 -> e2
sumMap f c = (merge (+) 0) (map f c)
编译报错:
无法从上下文 (Coll c e) 中推断出 (Coll c e2) [...] 可能的修复:将 (Coll c e2) 添加到 sumMap [ 的类型签名的上下文中...]
所以我将sumMap :: (Num e2) => (e1 -> e2) -> c e1 -> e2 替换为sumMap :: (Num e2, Coll c e2) => (e1 -> e2) -> c e1 -> e2,但随后又出现了另一个错误:
无法从上下文 (Coll c e) 中推断 (Coll c e0) [...] 可能的修复:添加修复这些类型变量的类型签名 [... ]
我很困惑,所以我将sumMap 的定义注释掉,然后运行:t (merge (+) 0) . (map (* 2)),得到[...] :: (Num c, Coll c1 c, Coll c1 e) => c1 c -> c。忽略它如何破坏我的变量名称,Coll c1 e 很奇怪; e 甚至没有在定义中使用!那为什么会在那里!?无论如何,然后我运行((merge (+) 0) . (map (* 2))) [1,2,3,4],它成功返回20。这里发生了什么?为什么这个功能只有在我不尝试将其与名称绑定时才起作用?
【问题讨论】:
-
"e 甚至没有在定义中使用!那为什么它在那里!?" - 这正是问题所在! e 没有在定义中使用,因此编译器永远无法确定它应该具有什么类型,但它必须在那里,因为该类是用 2 个参数声明的。顺便说一句,我预计这是一个学习练习,但你的课程只是
Foldable是伪装的。
标签: function haskell compiler-errors