2

This code is taken from https://wiki.haskell.org/Partial_application

I'm attempting to implement this function :

comp2 :: (a -> b) -> (b -> b -> c) -> (a -> a -> c)
comp2 f g = (\x y -> g (f x) (f y))

using

*Main> comp2 3 4

but receive exception :

<interactive>:19:1:
    Non type-variable argument in the constraint: Num (a -> b)
    (Use FlexibleContexts to permit this)
    When checking that `it' has the inferred type
      it :: forall a b c.
            (Num (a -> b), Num (b -> b -> c)) =>
            a -> a -> c
*Main> 

How to implement comp2 function ?

1
  • 2
    Note that comp2 == flip on, where on is defined in Data.Function. Commented May 26, 2016 at 21:48

2 Answers 2

7

You've implemented comp2 just fine. You just don't use it right. The arguments to comp2 are both functions. Is 3 a function? I daresay not.

Haskell compilers have an extremely open mind though – GHC assumes that a -> b could possibly have a Num instance (which is what's required to use numerical literals). Hence it doesn't give an error like Couldn't match type `a -> b` with numerical literal `3`, but tries to go on with the assumption that there must be such an instance because you are invoking it. But to actually search for that instance, the compiler needs to have FlexibleContexts enabled.

Prelude> comp2 3 4

<interactive>:9:1:
    Non type-variable argument in the constraint: Num (a -> b)
    (Use FlexibleContexts to permit this)
    When checking that ‘it’ has the inferred type
      it :: forall a b c.
            (Num (a -> b), Num (b -> b -> c)) =>
            a -> a -> c
Prelude> :set -XFlexibleContexts 
Prelude> comp2 3 4

<interactive>:11:1:
    Could not deduce (Num (a -> b0))
    from the context (Num (a -> b), Num (b -> b -> c))
      bound by the inferred type for ‘it’:
                 (Num (a -> b), Num (b -> b -> c)) => a -> a -> c
      at <interactive>:11:1-9
    The type variable ‘b0’ is ambiguous
    When checking that ‘it’ has the inferred type
      it :: forall a b c.
            (Num (a -> b), Num (b -> b -> c)) =>
            a -> a -> c
    Probable cause: the inferred type is ambiguous

This is still not as clear as we'd like, but it points out the problem: you try to use function types as number types.

Sign up to request clarification or add additional context in comments.

Comments

1

Are you sure you mean implement and not use? If you look at comp2 :: (a -> b) -> (b -> b -> c) -> (a -> a -> c), it is possible to see that comp2 takes two functions, f and g. To use comp2, you need to give it two functions and probably two values. Try this

comp2 (*2) (+) 2 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.