【发布时间】:2018-08-08 21:08:50
【问题描述】:
我试图了解这是如何工作的;在 GHCi 中:
foldMap (+3) (Just 5) :: Sum Int
产生结果
Sum {getSum = 8}
现在,foldMap 的类型是
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
并且从该类型中 foldMap 使用的函数的签名与使用的函数的签名(+3)不匹配:
(+3) :: Num a => a -> a
对
f :: Monoid m => a -> m
如果我也尝试这样的事情:
foldMap _ (Just 5) :: Sum Int
---------------------------------------
<interactive>:113:9: error:
* Found hole: _ :: Integer -> Sum Int
* In the first argument of `foldMap', namely `_'
In the expression: foldMap _ (Just 5) :: Sum Int
....
这也表明预期的函数是签名:: (Integer -> Sum Int),与 foldMap 声明中的签名一致,但与上面使用的 (+3) 不一致?我对 foldMap 的理解是它应用函数将 Foldable 实例的每个元素转换为 Monoid,然后可以折叠成单个值。
我假设编译器推断应该是什么类型(在上面的行中明确说明)但我不明白编译器如何“调整”函数的类型签名(+3)以便第一行编译?
【问题讨论】:
-
好吧
instance Num a => Num (Sum a)成立,这意味着5是Sum Int。 -
哎呀,“发现洞:
_ :: Integer -> Sum Int”令人难以置信的误导!它实际上应该类似于“找到洞:_ :: exists a. Num a *> a -> Sum Int”,但exists(forall的对偶)和(*>)((=>)的对偶)在 Haskell 中不存在(还没有?)。默认选择a ~ Integer,但其他选择也是有效的,尤其是Sum Int,因此该孔的另一个有效类型是Sum Int -> Sum Int——并且(+3)确实可以被赋予该类型。 -
@DanielWagner 我在禁用默认设置后得到
Found hole: _ :: a0 -> Sum Int。然后Ambiguous type variable ‘a0’ arising from the literal ‘5’ prevents the constraint ‘(Num a0)’ from being solved.不太破旧。默认版本确实值得。 -
@chi 啊,很好,我试过
-XNoMonomorphismRestriction,因为这是默认的通常 罪魁祸首,但没有帮助;我没想过要尝试default (),但是一旦我阅读了您的评论,很明显这是要走的路,而且错误的集合看起来要好得多!