缺点似乎不像我在第二个例子中所期望的那样工作。我错过了什么?
这里 cons 将一个元素添加到列表中,这很棒。
1:[2,3]
但是有了这个,它似乎将第一个元素放入列表 x 中,将尾部放入列表 xs 中:
let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs }
我真的不明白为什么会发生这种情况,这与递归有关吗?
提前致谢!
缺点似乎不像我在第二个例子中所期望的那样工作。我错过了什么?
这里 cons 将一个元素添加到列表中,这很棒。
1:[2,3]
但是有了这个,它似乎将第一个元素放入列表 x 中,将尾部放入列表 xs 中:
let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs }
我真的不明白为什么会发生这种情况,这与递归有关吗?
提前致谢!
该:
运算符可用于构造列表和解构列表,具体取决于您使用它的位置。如果你在表达式中使用它,它用于构造一个列表,就像你说的那样。当你在一个模式中使用它时,它会做相反的事情——它解构(分解)一个列表。
构建列表:
λ> 1:2:[3, 4]
[1,2,3,4]
解构列表:
λ> let first:second:rest = [1, 2, 3, 4]
λ> first
1
λ> second
2
λ> rest
[3, 4]
这同样适用于 Haskell 中的许多数据构造函数。您可以使用Just
来构造一个Maybe
值。
λ> let name = Just "John"
λ> :type name
name :: Maybe [Char]
但是,您也可以使用它来分解一个Maybe
值。
λ> let Just x = name
λ> x
"John"
这里发生了两件不同的事情。您的第一个示例使用(:)
运算符从元素1
和列表创建一个新列表[2,3]
。
1:[2,3]
您的第二个示例使用模式匹配。表达方式...
myInt (x:xs) = ...
...本质上说“如果参数 ofmyInt
包含一个附加到(可能为空)列表的元素,那么让我们调用第一个元素x
和 list xs
。” 这个例子可能会更清楚:
λ> let { myInt :: [Int] -> String ; myInt (x:xs) = "The first element is " ++ show x ++ " and the rest of the list is " ++ show xs}
λ> myInt [1,2,3]
"The first element is 1 and the rest of the list is [2,3]"
请注意,这仅在输入列表包含至少一个元素时才有效。
λ> myInt []
"*** Exception: <interactive>:9:34-127: Non-exhaustive patterns in function myInt
但是,我们可以像这样处理输入列表为空的情况:
λ> let { myInt :: [Int] -> String ; myInt (x:xs) = "The first element is " ++ show x ++ " and the rest of the list is " ++ show xs; myInt _ = "empty list"}
λ> myInt []
"empty list"