Prelude> let [x,y] = [3,4] in x*x+y*y
25
Prelude> let x:[y] = [3,4] in x*x + y*y
25
Prelude> let x:y = 3:4 in x*x+y*y
交互式的:6:5:错误:
*约束中的非类型变量参数:Num [a]
(使用FlexibleContexts允许此操作)
*在检查推断的类型
x :: forall a时。(Num a,Num [a])=> a
在表达式中:let x:y = 3:4 in x * x + y * y
在'it'的等式中:it = let x:y = 3:4在x * x + y * y中
有人可以解释前两个语句中发生了什么以及为什么第三条let ... in ..语句有错误。
在第三个示例中,let分配的右侧是:3:4。该:(缺点)运算符的类型签名a -> [a] -> [a]:它需要在其左侧的值,并在右侧该类型的值的列表。在这种情况下,3是a,但4不是a([a])的列表;这也是一个a。这是无效的。
鉴于到目前为止的锻炼形式,您可以通过两种方法解决此问题:with 3:[4]或with 3:4:[]。
如果您现在尝试运行代码,则会发现它在上失败x * x + y * y。这是因为你的模式匹配受让人x对3,并y以[4](一个单列表)。列表本身不能相乘,也不能添加到数字中。因此,我们再次在左侧使用解决方案:
let x:y:[] = 3:4:[]
in x * x + y * y
Run Code Online (Sandbox Code Playgroud)
如果我们添加了太多的类型注释,则可以希望看到问题出在哪里:
-- These work fine
-- let [x, y] = [3, 4] in ...
example1 = let [(x :: a), (y :: a)] :: [a]
= [(3 :: a), (4 :: a)] :: [a]
in x * x + y * y
-- let x:[y] = [3, 4] in ...
example2 = let ((x :: a) : ([(y :: a)] :: [a])) :: [a]
in x * x + y * y
-- This is the incorrect implementation
-- let x:y = 3:4 in ...
example3 :: (Num a) => a
example3 = let (x :: a) : (y :: [a]) -- (:) :: a -> [a] -> [a]
= (3 :: a) : (4 :: a) -- 4 :: a is invalid here: require [a]
in (x :: a) * (x :: a)
+ (y :: [a]) * (y :: [a]) -- Trying to multiply two lists
-- This is the fixed implementation
-- let x:y:[] = 3:4:[] in ...
example3' :: (Num a) => a
example3' = let ((x :: a) : (y :: a) : ([] :: [a])) :: [a]
= ((3 :: a) : (4 :: a) : ([] :: [a])) :: [a]
in x * x + y * y
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
82 次 |
| 最近记录: |