riley lyman
riley lyman

Reputation: 327

Non Type-Variable Argument Error

I am trying to write my own version of the take function in Haskell, and I don't understand where I am going wrong. This is my code:

take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n xs
    | n <= 0  = []
    | null xs = []
    | otherwise = first : rest 
    where first = head xs
          rest  = take' (n - 1) (tail xs)

To my understanding, specifying (Num i, Ord i) => i ... at the beginning of the function means that I should be able to pass in a negative integer. But when I try take' -1 [1..10] in the interactive interpreter, I get this error:

*Main> take' -1 [1..10]

<interactive>:154:1: error:
    * Non type-variable argument
        in the constraint: Num (i -> [a2] -> [a2])
      (Use FlexibleContexts to permit this)
    * When checking the inferred type
        it :: forall i a1 a2.
              (Ord i, Num i, Num a1, Num (i -> [a2] -> [a2]),
               Num ([a1] -> i -> [a2] -> [a2]), Enum a1) =>
              i -> [a2] -> [a2]

I tried enabling FlexibleContexts in my code and that didn't change anything. To my understanding, I need Num i since I decrement i in the where statement, and I need Ord i since there needs to be a way to count how many elements I want to take. What am I getting wrong here?

Upvotes: 1

Views: 74

Answers (1)

sepp2k
sepp2k

Reputation: 370445

take' -1 is interpreted as subtracting 1 from take', which is an error because you can't subtract something from a function. You want take' (-1) instead.

Note that this is not specific to your definition of take'. The same thing would have happened with the regular take as well.

Upvotes: 7

Related Questions