Home > database >  Composition with lambda expressions haskell
Composition with lambda expressions haskell

Time:05-06

I try a dummy example of using composition with lambda expression. The below code compile, but it doesn't run when I try (f.g) 3 2

f x = x^2
g x = 5*x

f.g = \x -> f(g x)
    

It gives such an error:

Ambiguous occurrence `.'
It could refer to
   either `Prelude..',
          imported from `Prelude' at list3.hs:1:1
          (and originally defined in `GHC.Base')
       or `Main..', defined at list3.hs:42:3.

Can somebody please tell me where is the problem?

CodePudding user response:

You defined a composition operator that exists along side the one imported from the Prelude. There's nothing wrong with the definition; the problem occurs when you try to use it, as the compiler can't tell if something like

main = print $ f . g $ 10

is supposed to use . from the Prelude or . from your Main module.

One solution is to simply be explicit about which of the two you want.

f . g = \x -> f (g x)

main = print $ f Main.. g $ 10

or to not import the Prelude version in the first place.

{-# LANGUAGE NoImplicitPrelude #-}

import Prelude hiding ((.))

-- Now this is the *only* definition.
f . g = \x -> f (g x)

main = print $ f . g $ 10

CodePudding user response:

As explained in the excellent answer by chepner, your '.' dot operator is in conflict with the regular '.' operator implicitly imported from the Haskell Prelude. This is what the error message means.

Fortunately, the Unicode character set is supported by the Haskell compiler, and it happens to offer the proper function composition character as seen in math books, that is '∘', in decimal position 8728.

And this '∘' operator is NOT (as yet) defined by the Prelude.

Hence, the following code works fine:

main :: IO ()
main = do
    let
         -- our own function composition operator:
         fna ∘ fnb  =  \x -> fna (fnb x)  -- Unicode character #8728 (decimal)

         f x    =   x * x
         g x    =   5 * x
         h      =   f ∘ g  -- composed function

         res    =   h 7
    putStrLn $ "res = "    (show res)

and it prints a result of 1225, as you would expect.

  • Related