TL; DR:纯粹由于功能组成而导致GHCi中的类型不匹配错误的原因是什么?看到GHCi评估以下代码很奇怪:
foldl (a . b . c) crackle pop <- GHCi evaluates this`
Run Code Online (Sandbox Code Playgroud)
...只是在我们尝试评估以下内容后给出错误:
let snap = a . b . c <- GHCi evaluates this
foldl snap crackle pop <- GHCi reports an error (!)
Run Code Online (Sandbox Code Playgroud)
版本较长:
我对GHCi中观察到的内容感到困惑,我希望有人可以解释一下(图片说明如下):

我们在上面看到了什么?:
首先,我们有一个变量b,它绑定到以下列表:[(2,["Dipak"]), (2,["Andrew"]),(2,["Keone"])]. b是类型的[(Int,[String])].(请参阅ghci>上面屏幕截图中的第一个提示和结果输出.)
然后我们执行折叠b,将其转换为以下类型:Map (Integer, [String]).我们通过使用基于insertWith (++)作为empty地图的起始累加器的折叠函数来实现.该功能如下(与ghci>上面屏幕截图中的第二个提示相同.(参见ghci>上面的第二个提示.)
foldl' (flip $ uncurry (Map.insertWith (++))) (Map.fromList []) b
好的,很酷; 到现在为止还挺好
鉴于foldl'上面的功能是满口的,我决定编写一个foldingFunc等于的折叠函数(命名)flip $ uncurry (Map.insertWith (++)).这只是foldl'上面表达式中的第一个参数.(参见上面let第三个ghci>提示中的表达式.)
这是我感到困惑的地方:作为例行检查,我执行与foldl'上面相同的操作,除了foldingFunc(代替flip $ uncurry (Map.insertWith (++))),这应该只是一个整容变化...现在GHCi报告类型不匹配错误(上面的详细信息).
有人可以帮我理解为什么在这种情况下函数组成会导致错误(由于类型更改)?我应该做些什么呢?
ghci扩展的违约规则和可怕的单态限制的动态二重奏再次打击!
我猜你正在使用一个稍微过时的ghci,7.6或更早版本.
会发生什么是foldingFunction最普遍的类型
foldingFunction :: Ord a => Map a [b] -> (a,[b]) -> Map a [b]
Run Code Online (Sandbox Code Playgroud)
但是,由于它是没有参数的顶级定义,并且你的ghci版本仍然具有单态限制,这不是一个"好"类型(因为上下文而是多态Ord a),并且默认规则启动.ghci尝试找到一个默认实例Ord a- 通常这会失败(因为没有类似的Num约束),但ghci也认为()是一个可能的默认值.这是有效的,所以如果你问ghci foldingFunction你会得到什么类型
foldingFunction :: Map () [b] -> ((), []) -> Map () []
Run Code Online (Sandbox Code Playgroud)
这是您的类型错误来自哪里.(我希望我猜对了!)
有几种方法可以解决这个问题:
foldingFunction:如果你使用foldingFunction m = (flip $ uncurry (Map.insertWith (++))) m或者更好,foldingFunction m (a,bs) = insertWith (++) a bs m它将开始工作.{-# LANGUAGE NoMonomorphismRestriction #-}在文件顶部添加编译指示或通过输入:set -XNoMonomorphismRestrictionghci的命令行以交互方式执行此操作来关闭单态限制.默认情况下关闭DMR和扩展默认规则都是最新的(最近几年)添加到ghci,所以甚至可能是你正在使用的书或文本太旧了:)