当我尝试运行以下功能时,我收到错误。
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]
有人可以解释一下,如何解决这个问题?这个错误究竟传达了什么?
答案 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]
。为了满足这两个要求,1
,2
和3
的数字文字必须代表元组,如果您定义了类实例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]