chenzhongpu
chenzhongpu

Reputation: 6871

Non type-variable argument when checking the inferred type in Haskell

I am new to Haskell. I implement the drop on my own.

myDrop n xs = if n <= 0 || null xs
              then xs
              else myDrop (n - 1) (tail xs)

But I call it when n < 0, for example, myDrop -2 [1, 2, 3]. It will raise an error:

<interactive>:23:1: error:
    • Non type-variable argument
        in the constraint: Num ([t] -> t1 -> [a] -> [a])
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall t a t1.
              (Num ([t] -> t1 -> [a] -> [a]), Num (t1 -> [a] -> [a]), Num t,
               Num t1, Ord t1) =>
              t1 -> [a] -> [a]

Upvotes: 1

Views: 246

Answers (1)

luqui
luqui

Reputation: 60463

It shouldn't be possible that when you call a function with two different arguments of the same type one will raise a type error and the other will pass. So something else is going on here.

In particular,

myDrop -2 [1,2,3]

isn't interpreted the way you expect. It's interpreted like this

myDrop - (2 [1,2,3])

that is, subtracting the number 2 called (as a function) with the list [1,2,3] as its argument from myDrop. In other words, utter nonsense. That's why the type error is so weird looking.

In Haskell negative constants require parentheses:

myDrop (-2) [1,2,3]

Upvotes: 5

Related Questions