Home > Net >  Couldn't match expected type `t0 -> t' with actual type `Rat'
Couldn't match expected type `t0 -> t' with actual type `Rat'

Time:11-12

I'm doing homework and one of the tasks is to make a function that normalises a rational number. Rational numbers here are defined by two integers ( which is already determined by the professor so I can't change that). This is what I came up with:

data Rat = Rat Integer Integer

normaliseRat :: Rat -> Rat
normaliseRat (Rat a b) = Rat (a `div` gcd a b) (b `div` gcd a b)

When I try to run the function I get this error:

<interactive>:2:1: error:
    * Couldn't match expected type `t0 -> t' with actual type `Rat'
    * The function `normaliseRat' is applied to two value arguments,
        but its type `Rat -> Rat' has only one
      In the expression: normaliseRat 6 9
      In an equation for `it': it = normaliseRat 6 9
    * Relevant bindings include it :: t (bound at <interactive>:2:1)

I'm completely new to Haskell and functional programming so forgive me if it's a simple solution.

CodePudding user response:

normaliseRat expects a single Rat argument, not the two integers you would use to build a Rat value. Assuming your Rat type has an appropriate Show instance,

> normaliseRat (Rat 6 9)
Rat 2 3

If you wanted a smart constructor for Rat that did take two Integer arguments, that would be something like

mkRat :: Integer -> Integer -> Rat
mkRat n d = let gcd' = gcd n d
                n' = n `div` gcd'
                d' = d `div` gcd'
            in Rat n' d'

> mkRat 6 9
Rat 2 3

(The purpose of a smart constructor is to prevent you from creating a value like Rat 6 9 in the first place, as long as you always use mkRat in place of using Rat directly. mkRat can also be defined in terms of your existing normaliseRat:

mkRat :: Integer -> Integer -> Rat
mkRat n d = normaliseRat (Rat n d)

)

  • Related