2014-11-06 62 views
3

TL; DR:什么会导致GHCi中的类型不匹配错误纯粹是由于函数组合?这是奇怪地看到GHCI评估以下代码:Haskell:函数组合导致类型不匹配错误

foldl (a . b . c) crackle pop  <- GHCi evaluates this` 

......之后我们试图评估以下只给一个错误:

let snap = a . b . c    <- GHCi evaluates this 
foldl snap crackle pop    <- GHCi reports an error (!) 

较长的版本:

我对我在GHCi观察到的东西感到困惑,并希望有人能解释它(描述如下图所示):

enter image description here

做什么我们上面看到?:

  • 首先,我们有一个变量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表达式在第三个。提示以上)

  • 这是我感到困惑:作为常规检查,我执行相同的foldl'如上,除了与foldingFunc(代替flip $ uncurry (Map.insertWith (++))),它应该简单地是一个外观上的改变...现在GHCi报告类型不匹配错误(详情如上)。

有人能帮我理解为什么在这种情况下,函数组合导致错误(由于类型改变)?我应该做什么不同?

+2

你打开了“MonomorphismRestriction”吗? “b”和“foldingFunc”的类型是什么? (用ghci中的':t'检查类型。) – Rufflewind 2014-11-06 05:09:05

+0

宾果游戏,刚刚关闭它,现在它正常工作。非常感谢。如果你复制粘贴你的评论到一个答案,我会(愉快地!)接受 – iceman 2014-11-06 05:22:33

+0

yatima2975击败了我。 :) – Rufflewind 2014-11-06 05:53:27

回答

8

ghci的延长违约规则和可怕的单态限制罢工动态二重奏!

我猜你正在使用稍微过时的ghci,版本为7.6或更早。

什么情况是,foldingFunction具有作为最普遍的类型

foldingFunction :: Ord a => Map a [b] -> (a,[b]) -> Map a [b] 

然而,因为它是不带参数的顶层定义和您的ghci的版本仍具有单态的限制,这是不是一个'好'类型(它是多态的,因为上下文Ord a),并且默认规则启动了。ghci试图找到Ord a的默认实例 - 通常这会失败(因为没有类似Num的约束),但ghci也考虑()作为可能的默认值。这样的作品,所以,如果你 ghci的为foldingFunction类型,你会得到

foldingFunction :: Map() [b] -> ((), []) -> Map() [] 

这是你的类型的错误来源。 (我希望我已经猜中!)


周围有这样的几种方法:

  1. 添加参数foldingFunction:如果您使用foldingFunction m = (flip $ uncurry (Map.insertWith (++))) m也许更好foldingFunction m (a,bs) = insertWith (++) a bs m它会启动加工。
  2. 通过在文件顶部添加一个{-# LANGUAGE NoMonomorphismRestriction #-}杂注或通过在ghci的命令行中输入:set -XNoMonomorphismRestriction以交互方式关闭单态限制。
  3. 升级至更新版本的GHC(7.8.3对我来说无效)。

默认情况下DMR都处于关闭状态,扩展的默认规则相当近(最近几年)添加到ghci中,所以甚至可能是因为您使用的书或文本太旧:)

+1

谢谢!是的,我使用7.6.3 ...时间来更新。 – iceman 2014-11-06 16:53:19