Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implementing curry function

I'm currently reading "programming in haskell" by Graham Hutton and just reached currying and function composition.In the exercise portion, there is the task to implement the curry function from scratch which is already present in the prelude module.

Here's my implementation but it's not working.Can anybody explain(I'm new to functional programming) why it's not working

my_curry :: ((a ,b) -> c) -> (a -> b -> c)
my_curry origFunc = origFunc.combine
                    where
                         combine e f = (e, f)

here's the error [added]

[1 of 1] Compiling Main             ( higher_order.hs, interpreted )

  higher_order.hs:92:30:
      Couldn't match type `t0 -> (a, t0)' with `(a, b)'
      Expected type: a -> (a, b)
        Actual type: a -> t0 -> (a, t0)
      In the second argument of `(.)', namely `combine'
      In the expression: origFunc . combine
      In an equation for `my_curry':
          my_curry origFunc
            = origFunc . combine
            where
                combine e f = (e, f)
like image 399
basic_bgnr Avatar asked May 01 '26 22:05

basic_bgnr


1 Answers

The issue is that . is meant to take to single argument functions and glue them together,

In this case combine has the type a -> b -> (a, b). So it's first argument is a and it's return type is b -> (a, b) (remember that -> groups to the right). So . has the type

(.) :: (b -> c) -> (a -> b) -> a  -> c

Since combine is the second argument haskell is going to unify .s type variables like

(.).a ~ combine.a
(.).b ~ (combine.b -> (combine.a, combine.b))

I'm using foo.bar to mean the type variable bar from the definition of foo. Next we feed this into origFunc which as the type (a, b) -> c. Now when we try to fit this into . we get

(.).b ~ my_curry.(a, b)
(.).c ~ my_curry.c

But wait! b can't be both (a, b) and b -> (a, b) and thus the type error.

Instead we have two choices, we can create a new type of composition

(..) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
f .. g = \a b -> f (g a b)

Notice how this allows g to take two arguments, and your function becomes

 my_curry origFunc = combine .. origFunc

Or we can just use currying

 my_curry origFunc x y = origFunc (x, y)
like image 144
Daniel Gratzer Avatar answered May 03 '26 19:05

Daniel Gratzer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!