Search code examples
functional-programmingpolymorphismsmlpolyml

A function of type: ('a -> ('b -> 'c)) -> ('a -> 'b) -> ('a -> 'c) in Standard ML


Whilst revising for my programming languages exam, there are a few type inference questions for the Standard ML section, I can do most of them by doing type inference in my head, and I'm quite good at it, however there is one question that leaves me stumped.

I have to write a function of type:

('a -> ('b -> 'c)) -> ('a -> 'b) -> ('a -> 'c)

So in my head I should have a function with two arguments that are functions, f and g. Both would take an argument, x, but I cannot add that argument x into this function as it only takes two arguments, so I am left to create this function using the o operator, for pipe-lining functions.

So f takes an argument, and returns a function g takes an argument, and returns a value. Then the overall function takes a value and returns a value.

I'm not sure how I can apply f and g using only the o operator to imply those rules.

Any help would be extremely appreciated :) Thanks, Ciaran


Solution

  • As you already mentioned, you need to write a function of two arguments:

    fun my_function f g = body
    

    where f : 'a -> 'b -> 'c and g : 'a -> 'b and body : 'a -> 'c.

    Since body has type 'a -> 'c, we can write it as

    body = fn x => body'
    

    where body' has type 'c and x : 'a.

    Observe, that f x : 'b -> 'c and g x : 'b, and if you have a function of type 'b -> 'c and a value of type 'b it's easy to construct a value of type 'c by applying the function to the argument: (f x) (g x).

    The above gives us:

    fun my_function f g = fn x => (f x) (g x)
    

    or, alternatively, moving x to the left-hand side of the definition we get:

    fun my_function f g x = f x (g x)
    

    By the way, if you are familiar with combinatory logic, then you could notice that the resulting function represents the S combinator.