Haskell:list comprehension:约束中的非类型变量参数:Num [t]

时间:2016-04-12 04:31:39

标签: haskell

当我尝试运行以下功能时,我收到错误。

Prelude> let squareSum list = [result | (x, y, z) <- list, result <- x^2 + y^2 + z^2] 

<interactive>:4:5:
    Non type-variable argument in the constraint: Num [t]
    (Use FlexibleContexts to permit this)
    When checking that ‘squareSum’ has the inferred type
     squareSum :: forall t. Num [t] => [([t], [t], [t])] -> [t]

有人可以解释一下,如何解决这个问题?这个错误究竟传达了什么?

2 个答案:

答案 0 :(得分:5)

原始问题

你发布了:

Prelude> let squareSum list = [result | (x, y, z) <- list, result <- x^2 + y^2 + z^2]

<interactive>:3:5:
    Non type-variable argument in the constraint: Num [t]
    (Use FlexibleContexts to permit this)
    When checking that ‘squareSum’ has the inferred type
      squareSum :: forall t. Num [t] => [([t], [t], [t])] -> [t]

这来自推理,即计算x^2 + y^2 + z^2必须是一个列表,因为它在列表推导中使用它作为值的来源(result <- ...)。如果这是一个列表,那么数学运算符将超过列表类型值,这意味着您的初始变量list必须是列表元组的列表([([t],[t],[t])]),并且每个列表必须以某种方式是有效数字(Num [t])。

评论问题

Prelude> let squareSum list = [ x^2 + y^2 + z^2 | (x, y, z) <- list]
Prelude> squareSum [1,2,3]

<interactive>:9:1:
    Non type-variable argument in the constraint: Num (t, t, t)
    (Use FlexibleContexts to permit this)
    When checking that ‘it’ has the inferred type
      it :: forall t. (Num t, Num (t, t, t)) => [t]

现在您说变量list包含元组((x, y, z) <- list),但您将列表定义为[1,2,3]。为了满足这两个要求,123的数字文字必须代表元组,如果您定义了类实例Num (t, t, t),则可以使用这些元数。

你想要什么

卡特已经告诉过你这个解决方案了,但是你没有把它应用到合理的清单上。我们如何定义解决方案并给它一个明确的类型,以减少混淆!

Prelude> :{
Prelude| let squareSum :: [(Int,Int,Int)] -> [Int]
Prelude|     squareSum list = [ x^2 + y^2 + z^2 | (x, y, z) <- list]
Prelude| :}
Prelude> squareSum [(1,2,3), (4,5,6)]
[14,77]

成功!我们提供了两个元组并得到两个Int结果,是的!

答案 1 :(得分:-1)

以下片段解决了我的问题。

Prelude> let processData fun list = [y | x <- list, let y = fun x]
Prelude> let sumSquare (x, y, z) = x^2 + y^2 + z^2
Prelude> 
Prelude> processData sumSquare [(1, 2, 3), (4, 5, 6)]
[14,77]