gpt4 book ai didi

haskell - Haskell 中的推断类型不够通用

转载 作者:行者123 更新时间:2023-12-04 22:30:55 32 4
gpt4 key购买 nike

我正在编写一个程序,它接收一个元素列表(这样的列表必须同时包含整数和小数)并给出一个切割总和列表:

  • 结果列表的第一个元素是整个列表的总和
  • 秒是没有头部的列表之和
  • 第三个是没有头的列表和第二个元素的总和
  • 等等。

  • 到目前为止,我的结果是:
    cuttingSum :: Num a => [a] -> [a]
    cuttingSum l =
    let
    cuttingSum_iter [] res = reverse (res)
    cuttingSum_iter ll res =
    cuttingSum_iter (tail ll) ((foldl (+) 0 ll) :: res)
    in
    cuttingSum_iter l []


    main = do
    print $ cuttingSum [1,2,3]

    我收到错误:
     ERROR "task9-02-1.hs":5 - Inferred type is not general enough
    *** Expression : foldl (+) 0 ll
    *** Expected type : a
    *** Inferred type : _26

    我正在使用 Hugs,因为它是任务要求,但 ghci 也显示了某种类似的错误。有什么问题?

    最佳答案

    问题只是一个错字,你有 foldl (+) 0 ll :: res 而不是 foldl (+) 0 ll : res ,只有一个 : 。这是因为 :: 表示表达式的类型。当你有

    cuttingSum_iter ll res = cuttingSum (tail ll) ((foldl (+) 0 ll) :: res)

    这相当于
    cuttingSum_iter ll res = cuttingSum (tail ll) ((foldl (+) 0 ll) :: b)

    因为 res 作为参数和 res 作为类型存在于不同的命名空间中。在类型命名空间中,任何以小写字母开头的标识符都是类型变量,正如我们所知,变量的名称对编译器无关紧要,只对程序员而言。 从这一点来看,我将其称为 b 以避免与 res 参数混淆。

    由于您告诉编译器表达式 foldl (+) 0 ll 的类型为 b ,因此它无法通过类型检查阶段。编译器可以计算出 ll 至少是一个列表,在 foldl (+) 0 中使用它意味着它必须包含 Num 元素,因此 foldl (+) 0 ll 必须具有 Num a => a 类型。这与 b 类型不匹配,因为 b 没有 Num 约束。这就是导致您看到的错误消息的原因
    ERROR "task9-02-1.hs":5 - Inferred type is not general enough

    推断类型不够通用,因为推断类型具有 Num 约束。

    在 GHC 中,你会得到错误
    Couldn't match type ‘t’ with ‘res’
    because type variable ‘res’ would escape its scope
    This (rigid, skolem) type variable is bound by
    an expression type signature: res
    at <interactive>:13:57-79
    Expected type: [res]
    Actual type: [t]
    Relevant bindings include
    ll :: [t] (bound at <interactive>:13:21)
    cuttingSum_iter :: [t] -> [a] -> [a] (bound at <interactive>:12:5)
    In the third argument of ‘foldl’, namely ‘ll’
    In the second argument of ‘cuttingSum_iter’, namely
    ‘((foldl (+) 0 ll) :: res)’

    对我来说,这个更清楚一点,因为它在第二行提到了“类型变量 res”,并说它期望它有 [res] 而期望类型 [t] ,其中 cuttingSum_iter 具有类型 [t] -> [a] -> [a] 。看到它提到了“type variable res”和“Expected type: [res]”,这至少更多地指向了问题所在,尽管它仍然不能立即清楚实际问题是什么。

    关于haskell - Haskell 中的推断类型不够通用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26004140/

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