Home > other >  Haskell: Couldn't match expected type
Haskell: Couldn't match expected type

Time:03-28

I'm trying to learn Haskell and the small bit of sample code I tried to understand is compiling, but while applying the code I was running into a "Couldn't match expected type" error. Can anyone give me some guidance as to what I'm doing wrong/how I should go about this?

This code was given in a lecture:

> mult :: Integer -> (Integer, Integer-> Integer )
> mult x = (x,(*x))

Executing snd (mult 3) 5 as I was told in the lecture I get

15

However when executing (mult 3) 5 I get the following error

<interactive>:133:1: error:
    • Couldn't match expected type ‘Integer -> t’
                  with actual type ‘(Integer, Integer -> Integer)’
    • The function ‘mult’ is applied to two arguments,
      but its type ‘Integer -> (Integer, Integer -> Integer)’
      has only one
      In the expression: (mult 3) 5
      In an equation for ‘it’: it = (mult 3) 5
    • Relevant bindings include it :: t (bound at <interactive>:133:1)

Seeing the error I have tried to apply mult with one argument mult 3 which resulted in the following error

<interactive>:135:1: error:
    • No instance for (Show (Integer -> Integer))
        arising from a use of ‘print’
        (maybe you haven't applied a function to enough arguments?)
    • In a stmt of an interactive GHCi command: print it

Why can't I use mult without the snd function?

CodePudding user response:

(Integer, Integer -> Integer)

This is not a function. It might look kind of like a function of two arguments, but it's actually parenthesized as (Integer, (Integer -> Integer))

so it's a tuple, where the first thing is just an ordinary number and the second is a function.

mult :: Integer -> (Integer, Integer -> Integer)
mult x = (x, (*x))

Here, we take a number x and return a 2-tuple. The first element of this tuple is just the number x, nothing more and nothing less. The second element is a function which multiplies by x. These are two distinct values, not tied together in any way.

fst (mult 3)

This is the first element of the tuple, which is just a number. In this case, we'll get 3.

snd (mult 3)

This is the second element of the tuple, a function from Integer to Integer. We can't print out functions in Haskell (since they don't implement Show), so we have to apply it to an argument in order to get a result.

snd (mult 3) 5 -- Or, equivalently, (snd (mult 3)) 5

This applies the function "multiply by 3" to the number 5, so we get 5 times 3, or 15.

(mult 3) 5

This takes a tuple mult 3 (whose value is (x, (* x))), and attempts to apply it to a number. In Haskell, only functions can be given arguments, and a tuple is not a function, so you get an error that basically says "I expected a function here, but I got a tuple".

CodePudding user response:

Why can't I use mult without the snd function?

Because mult 5 returns a 2-tuple, it returns (5, (* 5)), so the first item is an Integer whereas the second is a function with type Integer -> Integer.

You can not use this 2-tuple as a function when you apply 3 to it. What would the result of (5, (* 5)) 3 be? By using snd (5, (* 5)) it returns (* 5), and then you can use that for (* 5) 3, which is 15.

Furthermore you can not use show f with f a function, since for a generic function, that can not produce output. Using printing the result of mult 3 is thus not possible, you can print fst (mult 3) for example, which is 3.

  • Related