Reputation: 285
Cons doesn't seem to work as I would expect in the second example. What am I missing?
Here cons adds an element to a list, which is great.
1:[2,3]
But with this one it seems to put the first element into list x and the tail into list xs:
let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs }
I don't really see why this would happen, is it something to do with recursion?
Thanks in advance!
Upvotes: 8
Views: 3644
Reputation: 15028
The :
operator can be used to both construct a list and deconstruct a list, depending on where you use it. If you use it in an expression, it is used for constructing a list, just like you said. When you use it in a pattern, it does the reverse – it deconstructs (takes apart) a list.
Constructing a list:
λ> 1:2:[3, 4]
[1,2,3,4]
Deconstructing a list:
λ> let first:second:rest = [1, 2, 3, 4]
λ> first
1
λ> second
2
λ> rest
[3, 4]
The same applies for many data constructors in Haskell. You can use Just
to construct a Maybe
value.
λ> let name = Just "John"
λ> :type name
name :: Maybe [Char]
However, you could also use it to take apart a Maybe
value.
λ> let Just x = name
λ> x
"John"
Upvotes: 11
Reputation: 8126
There are two different things happening here. Your first example uses the (:)
operator to create a new list from the element 1
and the list [2,3]
.
1:[2,3]
Your second example uses pattern matching. The expression...
myInt (x:xs) = ...
...essentially says "if the argument of myInt
consists of an element prepended to a (possibly empty) list, then let's call the first element x
and the list xs
." This example may make it clearer:
λ> 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]"
Note that this will only work if the input list contains at least one element.
λ> myInt []
"*** Exception: <interactive>:9:34-127: Non-exhaustive patterns in function myInt
However, we can handle the case where the input list is empty like this:
λ> 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"
Upvotes: 9