gpt4 book ai didi

Haskell:函数组合导致类型不匹配错误

转载 作者:行者123 更新时间:2023-12-01 09:24:54 25 4
gpt4 key购买 nike

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

enter image description here

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

  • 首先,我们有一个变量b,它绑定(bind)到以下列表:[(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' 的第一个参数。 (参见上面第三个 ghci> 提示中的 let 表达式。)

  • 这是我感到困惑的地方:作为例行检查,我执行与上面相同的 foldl',除了 foldingFunc (代替 翻转 $ uncurry (Map.insertWith (++))) 这应该只是一个外观更改...现在 GHCi 报告类型不匹配错误(详情见上文)。

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

最佳答案

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

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

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

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

然而,因为它是一个没有参数的顶级定义,而且你的 ghci 版本仍然有单态限制,所以这不是一个“好的”类型(它是多态的,因为上下文 Ord a),然后默认规则开始生效。ghci 尝试为 Ord a 找到默认实例 - 通常这会失败(因为没有 Num-like 约束),但 ghci 也将 () 视为可能的默认值。这行得通,所以如果向 ghci 询问 foldingFunction 的类型,你会得到

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

这是您的类型错误的来源。 (希望我猜对了!)


有几种方法可以解决这个问题:

  1. foldingFunction 添加一个参数:如果你使用 foldingFunction m = (flip $ uncurry (Map.insertWith (++))) m 或者更好的 foldFunction m (a,bs) = insertWith (++) a bs m 它将开始工作。
  2. 关闭单态限制,方法是在文件顶部添加 {-# LANGUAGE NoMonomorphismRestriction #-} pragma,或者输入 :set -XNoMonomorphismRestriction 在 ghci 的命令行中。
  3. 升级到更新版本的 GHC(7.8.3 对我有用)。

默认情况下关闭 DMR 和扩展默认规则都是最近(过去几年)对 ghci 的补充,因此甚至可能是您使用的书籍或文本太旧了 :)

关于Haskell:函数组合导致类型不匹配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26772007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com