【发布时间】:2021-05-12 07:04:45
【问题描述】:
正如标题所暗示的,我不确定方括号和括号在列表方面的区别。
定义了两个版本的 Haskell 的 insert,一个使用方括号,另一个使用括号:
insert' :: Int -> [Int] -> [Int]
insert' y [] = [y]
insert' y (x:xs) | y <= x = y:x:xs | otherwise = x : insert' y xs
----
insert' y [x:xs] | y <= x = y:x:xs | otherwise = x : insert' y xs
insert' 的第二个定义不起作用的原因是什么?
它给出的错误信息,任何想知道的人:
test.hs:3:12: error:
• Couldn't match expected type ‘Int’ with actual type ‘[Int]’
• In the pattern: x : xs
In the pattern: [x : xs]
In an equation for ‘insert'’:
insert' y [x : xs]
| y <= x = y : x : xs
| otherwise = x : insert' y xs
|
3 | insert' y [x:xs] | y <= x = y:x:xs | otherwise = x : insert' y xs
|
【问题讨论】:
-
FWIW,这个问题经常出现。我总是觉得这很有趣,这会让人们专门寻找列表,而不是其他数据类型。例如,对于
data Tree a = Leaf | Branch (Tree a) (Tree a),没有人会问为什么Tree Branch l r不是匹配分支的正确模式。这不仅仅是前缀与中缀或命名空间冲突。同样,没有人问为什么Complex a :+ b不是匹配复数的正确模式。但是当它突然列出一些类型的残余应该/可能出现在模式中?人脑就是这么复杂! -
真的很简单。
[x]作为类型匹配任意长度的列表。[x]作为一个模式看起来完全一样。 -
IIRC 有人询问有关使用
Branch (Tree l) (Tree r)作为模式的问题。 -
@DanielWagner:我认为这是一个误导,因为
[x]类型的意思是“x类型的任意数量值的列表”,[] x的糖,而模式[x]表示“价值x的单一列表”,糖表示完全不同的东西,x : []=(:) x []。在一个上下文中使用[]作为“标志”使得在看起来相似的上下文中尝试使用这种方式是合理的。如果我们有其他类型的糖,比如Maybe拼写为data a? = () | a?,我敢打赌我们会看到类似的混淆f (x?)应该匹配什么。 -
@DanielWagner:我确实经常看到这种类型的困惑,无论是在这里还是在 /r/haskell 和 /r/haskellquestions 中的 Reddit 上。它会产生许多不同的范围/类型错误,并以多种方式表现出来——例如,
Maybe x而不是Just x;Branch a (Tree l) (Tree r)、Tree x l r、Tree (Branch x l r)或Branch b+left b/value b而不是Branch x l r;或给定data Tree = Leaf a | Node [Tree a],使用Node [Tree a]而不是Node ts。 H98data定义(相对于GADTSyntax)的教学困难导致将Foo f解释为f :: Foo。
标签: haskell recursion types pattern-matching type-mismatch