0
votes

I've started learning Haskell and got problems. I try to understand lambda and created function mo06

mo06 f x = if f x
           then x
           else x * x

I can call that in ghci:

λ mo06 (== 1) 1
1
λ mo06 (== 1) 3
9 

That works ok - no problems and no questions, but...

...I want to write my function as

mo08 f = fac (\x ->  if f x then x else x * x)

where

fac means factorial:

fac :: Num a => Int -> Int
fac n
  | n == 0    = 1
  | n > 0     = n * fac (n-1)
  | otherwise = error "fac only defined on natural numbers"

and call it as previously

mo08 (==1) 3

I try and got an error:

Could't match expected type 'a -> a' with actual type 'Int'.

Changing fac to (fromIntegr fac) did not help.

Thank you.

2
the Num a constraint on your Int -> Int function is meaningless; just remove it. alternatively, change from Int -> Int to a -> a.Erik Kaplun

2 Answers

0
votes

you have to move fac one in:

mo08 f = \xx -> fac (if f (xx) then xx else xx * xx)

or (if you like) move the xx to the left of the =:

mo08 f xx = fac $ if f (xx) then xx else xx * xx

to see why just look at \xx -> ... - this will be a function - here it will take an Int and produce an Int - same with fac :: Int -> Int - so when you try fac (\xx -> ...) you are actually trying to plug a function into fac (that is what the error is trying to tell you) - but if you move the fac inside the definition of the lambda it will work.

using composition

of course maybe you tried to use function-composition:

mo08 f = fac . (\xx -> if f (xx) then xx else xx * xx)

but as you can see you need to use the composition operator (.) ;)

0
votes

That lambda expression (of type a -> a) is not an integer, yet in mo08 you are trying to call fac on it - while fac expects an int. You will need to to put the fac call on the end result:

mo08 f = (\xx -> fac (if f xx then xx else xx * xx))

or alternatively use function composition:

mo08 f = fac . (\xx -> if f xx then xx else xx * xx)