Search code examples
haskellcons

Using cons with tail of tail in a list throws an error


I am a Haskell beginner and I am basically trying to understand why this fails:

Prelude> test
[2,3,4,1]
Prelude> tail $ tail test
[4,1]
Prelude> 2 : [4,1]
[2,4,1]
Prelude> 2 : tail $ tail test

<interactive>:27:1: error:
    • Couldn't match expected type ‘[Integer] -> t’
                  with actual type ‘[Integer]’
    • The first argument of ($) takes one argument,
      but its type ‘[Integer]’ has none
      In the expression: 2 : tail $ tail test
      In an equation for ‘it’: it = 2 : tail $ tail test
    • Relevant bindings include it :: t (bound at <interactive>:27:1)

<interactive>:27:5: error:
    • Couldn't match expected type ‘[Integer]’
                  with actual type ‘[a0] -> [a0]’
    • Probable cause: ‘tail’ is applied to too few arguments
      In the second argument of ‘(:)’, namely ‘tail’
      In the expression: 2 : tail
      In the expression: 2 : tail $ tail test
Prelude>

I see the error message "Probable cause: ‘tail’ is applied to too few arguments" but I don't understand enough to know what's causing it because that same expression just worked.


Solution

  • You need to be aware of operator grouping/precedence: 2 : tail $ tail test isn't the same as "cons 2 onto the value tail $ tail test" any more than 5 * 3 + 2 is "multiply the result of 3 + 2 by 5". In both cases, you need to add parentheses if that's the operation you want.