缺点似乎并不像我在第二个示例中所期望的那样工作。我错过了什么?Haskell的工作方式如何工作:
这里cons将一个元素添加到列表中,这非常棒。
1:[2,3]
但是这一个似乎把第一个元素到列表x和尾到列表的xs:
let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs }
我真的不明白为什么会发生这种事,是事用递归做什么?
在此先感谢!
缺点似乎并不像我在第二个示例中所期望的那样工作。我错过了什么?Haskell的工作方式如何工作:
这里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"
请注意,这里没有关于“:”的任何“特别” _all_值构造函数具有此属性。 – MathematicalOrchid
这里发生了两件不同的事情。您的第一个示例使用(:)
运算符从元素1
和列表[2,3]
中创建一个新列表。
1:[2,3]
你的第二个例子使用模式匹配。表达...
myInt (x:xs) = ...
...实际上是说“如果myInt
参数包括预先考虑到(可能为空)列表中的一个元素,那么让我们把第一个元素x
和列表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"
这是很好的记住haskell98允许*缀*类型构造,必须以“':'”开头,所以列表利弊的构造方法(需要两个参数)是这个一般规则的稍微特殊情况。 – jberryman