Search code examples
listhaskellfunctional-programmingpattern-matchingtail

Haskell basic - pattern matching vs list tail


I'm doing Set7.hs from haskell.mooc.fi/ Exercises7

-- Ex 5: reverse a NonEmpty list.
--
-- PS. The Data.List.NonEmpty type has been imported for you

-- below doesn't work
-- reverseNonEmpty :: NonEmpty a -> NonEmpty a
-- reverseNonEmpty  (h:|tail) = head reversed :| (tail reversed)
--   where 
--     reversed = reverse (h:tail)

-- below works
reverseNonEmpty :: NonEmpty a -> NonEmpty a
reverseNonEmpty (h :| tail) = head reversed :| revTail
  where
    reversed = reverse (h : tail)
    -- revTail = (tail reversed) - this doesn't work, but WHY???
    (_:revTail) = reversed

error message is:

Set7.hs:152:15: error:
    • Couldn't match expected type ‘[a] -> t’ with actual type ‘[a]’
    • The function ‘tail’ is applied to one argument,
      but its type ‘[a]’ has none
      In the expression: tail reversed
      In an equation for ‘revTail’: revTail = tail reversed
    • Relevant bindings include
        revTail :: t (bound at Set7.hs:152:5)
        reversed :: [a] (bound at Set7.hs:151:5)
        tail :: [a] (bound at Set7.hs:149:23)
        h :: a (bound at Set7.hs:149:18)
        reverseNonEmpty :: NonEmpty a -> NonEmpty a
          (bound at Set7.hs:149:1)
    |
152 |     revTail = tail reversed

I don't understand error message, what's wrong with tail reversed?

Why version with pattern matching (_:revTail) = reversed work?


Solution

  • reverseNonEmpty (h :| tail) = ...

    You've bound the name tail yourself, to refer to the list part of the NonEmpty. So this shadows the normal tail function, and there's no way to refer to that inside the body of reverseNonEmpty.

    This is why the error message is telling you that tail has type [a] and can't be applied to an argument.