Readler
Readler

Reputation: 149

GCF in Haskell with elses

Just started doing Haskell and I was given the task to do a basic GCF function similar to one for calculating a factorial. This is what I came up with

ggt :: Integer -> Integer -> Integer
ggt m n = if m < n then ggt n m
          else if n==0 then m
          else ggt n (m mod n)

I saw the responses here which, however, did in a completely different way than what I have been shown so far (I think it's called a guard pattern). My problem is that my code won't load and it says

 * Couldn't match expected type `(Integer -> Integer -> Integer)
                                    -> Integer -> Integer'
                  with actual type `Integer'
    * The function `m' is applied to two arguments,
      but its type `Integer' has none
      In the second argument of `ggt', namely `(m mod n)'
      In the expression: ggt n (m mod n)
Failed, modules loaded: none.

I don't understand why the types don't match (I have three Integers, two as an input, m and n, and one as a return) and, as a novice, I don't know what the second error really means.

I'd appreciate any and all help as well as all kind of explanations!

Cheers!

Upvotes: 2

Views: 131

Answers (1)

chepner
chepner

Reputation: 531708

Non-operator function names must be enclosed in backticks to be used in infix position. That is,

ggt :: Integer -> Integer -> Integer
ggt m n = if m < n then ggt n m
          else if n==0 then m 
          else ggt n (m `mod` n)

Otherwise, m is treated as the name of a function that takes the mod function as its first argument and n as its second. Such a function would have type (Integer -> Integer -> Integer) -> Integer -> Integer, but m :: Integer, hence the error message.

A cleaner way to define this (nested if expresssions aren't the easiest to read) would involve one simple guard.

ggt :: Integer -> Integer -> Integer
ggt m n | m < n = ggt n m
ggt m 0 = m
ggt m n = ggt n (m `mod` n)

or with a more involved guard instead of 3 separate pattern matches:

ggt :: Integer -> Integer -> Integer
ggt m n | m < n     = ggt n m
        | n == 0    = m
        | otherwise = ggt n (m `mod` n)

Upvotes: 1

Related Questions