2

I am new to functional programming and haskell in particular and have two questions abound as-pattern and the reduction of overlappings through using it. Giving the following code example:

last1 :: [a]          ->  a
last1    [x]          =   x
last1    (x:xs)       =   last xs

last2 :: [a]          ->  a
last2    [y]          =   y
last2    (y:ys@(_:_)) =   last ys

last1 should be non overlapping in comparison to last2. Lets take a look at the specific String f:[]. It would match to [x] and (x:xs) in last1.

In last2it would match to [y]. But not to (y:ys@(_:_)), because ys has to match (_:_) and just fulfills the first any pattern with [].

Are my assumptions correct?

Now take a look at the specific String f:o:o:[]. Now the pattern (y:ys@(_:_)) matches. In this case I am curious how the binding works. What is ys after the first call? I assume it is o:o:[].

froehli
  • 904
  • 1
  • 11
  • 35
  • Why not `x1:x2:_`? I don't see any reason to use "as" pattern here. – dredozubov May 21 '15 at 22:21
  • It is an example from my professor to descripe as-pattern and bindings. But it is more a mention than an explaination. – froehli May 21 '15 at 22:23
  • 1
    @dredozubov: How would you know what to recurse on in your example? – Guvante May 21 '15 at 22:31
  • @Guvante my point is: there is no need to alias subexpressions – dredozubov May 22 '15 at 22:25
  • @dredozubov: Your example drops the rest of the list and thus cannot work. `x1:x2:xs` could work but `x1:x2:_` cannot recurse on the remainder of the list making getting the last item impossible. – Guvante May 26 '15 at 16:41

2 Answers2

3

Your recursion is going to last in both cases, not last1/last2.

last1 should be non overlapping in comparison to last2. Lets take a look at the specific String f:[]. It would match to [x] and (x:xs) in last1.

It could match (x:xs) but it won't as pattern matching will only match the first success. Overlaps are not ambiguous in this regard (the first definition is always taken).

In last2it would match to [y]. But not to (y:ys@(_:_)), because ys has to match (_:_) and just fulfills the first any pattern with [].

Your phrasing is a bit odd but you are correct that f:[] cannot match to (y:ys@(_:_)) as the latter is basically matching on _:_:_ which isn't a match.

Now take a look at the specific String f:o:o:[]. Now the pattern (y:ys@(_:_)) matches. In this case I am curious how the binding works. What is ys after the first call? I assume it is o:o:[].

ys does equal o:o:[] (or "oo" or [o,o]).

Guvante
  • 18,775
  • 1
  • 33
  • 64
0

Both functions are the same in Haskell, as the first matching equation is used. Your second function is a bit more explicit about it, but the first is more idiomatic.

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139