【问题标题】:Haskell: function composition resulted in type-mismatch errorHaskell:函数组合导致类型不匹配错误
【发布时间】:2014-11-06 13:31:45
【问题描述】:

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

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 中观察到的情况感到困惑,希望有人能解释一下(图片下方的描述):

我们在上面看到了什么?:

  • 首先,我们有一个变量b,它绑定到以下列表:[(2,["Dipak"]), (2,["Andrew"]),(2,["Keone"])]b 的类型为 [(Int,[String])]。 (请参见上面屏幕截图中的第一个 ghci&gt; 提示和结果输出。)

  • 然后我们对b 执行折叠,将其转换为以下类型:Map (Integer, [String])。我们通过使用基于insertWith (++) 的折叠函数来实现这一点,这是一个empty 映射的起始累加器。功能如下(与上面截图中第二个ghci&gt;提示后面的相同。(见上面第二个ghci&gt;提示。)

    foldl' (flip $ uncurry (Map.insertWith (++))) (Map.fromList []) b

  • 好的,很酷;到目前为止,一切都很好

  • 1234563这只是上面表达式中foldl' 的第一个参数。 (参见上面第三个ghci&gt; 提示中的let 表达式。)
  • 这是我感到困惑的地方:作为例行检查,我执行与上述相同的foldl',除了foldingFunc(代替flip $ uncurry (Map.insertWith (++))),这应该只是表面上的改变......现在 GHCi 报告类型不匹配错误(详情见上文)。

有人可以帮我理解为什么在这种情况下函数组合会导致错误(由于类型更改)吗?我应该做些什么不同的事情?

【问题讨论】:

  • 您是否打开了MonomorphismRestrictionbfoldingFunc 的类型是什么? (在 ghci 中检查带有 :t 的类型。)
  • bingo,刚关掉它现在可以正常工作了。多谢。如果您将评论复制粘贴到答案中,我会(很高兴!)接受
  • yatima2975 打败了我。 :)
  • @Rufflewind:抱歉,我在输入解释时没有看到您的评论 :-)
  • @yatima2975 不,没关系。你比我更详细!

标签: haskell ghci


【解决方案1】:

ghci 的扩展默认规则和可怕的单态限制的动态二重奏再次来袭!

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

发生的情况是foldingFunction 具有最通用的类​​型

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

然而,因为它是一个没有参数的顶级定义,并且你的 ghci 版本仍然有单态限制,所以这不是一个“好”类型(它是多态的,因为上下文 @987654323 @),并且默认规则启动。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 的补充,因此甚至可能是您使用的书籍或文本太旧了 :)

【讨论】:

    猜你喜欢
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2015-04-30
    相关资源
    最近更新 更多