1
votes

Say we have a list in the parameter and pattern match on its head and tail separately so we use x:xs. This means that the inputs are split into a value x and a list xs.

So whatever is before the colon is treated as a single value and whatever is last in the colon notation will be the rest of the list with the single value x removed.

But what if I wanted to separate the last value from the rest of the values? It seems that this notation cant be used.

Update: i think i know how i would be able to find the last number using recursion, but is the true that you can't simply get it through some kind of pattern matching?

2

2 Answers

2
votes

The Haskell datatype [a] represents lists as a singly-linked cons list: the pattern match x:xs is not merely notation, but that's really how it is stored in memory, as a cons of the head and the rest.

As you mentioned in your update, you can write a function which goes through a list and splits it into an init part and a last element:

unsnoc :: [a] -> Maybe ([a], a)

You can use a view pattern to use it in pattern matching:

f (unsnoc -> Just (xs, x)) = ...
f [] = ...

And you can even wrap it into a pattern synonym:

pattern xs :> x <- (unsnoc -> Just (xs, x))

(or the bidirectional version

pattern xs :> x <- (unsnoc -> Just (xs, x)) where
  xs :> x = xs ++ [x]

)

allowing you to write

f (xs :> x) = ...
f [] = ...

Note however that all these approaches still require traversing the spine of the whole list, since they are all ultimately just calling your unsnoc function.

0
votes

For an arbitrary list you can't but for a fixed size list you can pattern match to the last element (or any other arbitrary element), for example

lastof4 [_,_,_,x] = x

lastof4 [1..4]
4