How to acess argument from a function passed as argument in SML

1.5k views Asked by At

I am new to coding SML and am still trying to understand pattern matching. I am trying to find out how to access an argument from a function passed as an argument in SML. For example, if a function takes 2 arguments, a function and an integer, how can I access the argument (for simplicity, assuming it only has one) that the argument function has. Does this question even make sense in SML? Here is some code, which doesn't work, but I think it illustrates what I am trying to do.

fun argumentExtraction (n,f) =
    case f of
        fn x => x
1

There are 1 answers

5
sepp2k On

A function doesn't have arguments, it takes arguments. You give arguments to the function and you get a result back. You can't ask the function what its arguments are because it doesn't have them yet. You are supposed to give the arguments to the function.


To make this perhaps a bit clearer, let us consider an example. Let's take the following functions:

fun add x y = x + y
fun plus1 x = x + 1

fun applyTwice f x = f (f x)

Now applyTwice takes a function and an argument and applies the function to the argument twice. We can call it like this:

applyTwice plus1 40

or like this:

applyTwice (add 1) 40

and in both cases the answer is going to be 42 (because that's the value of plus1 (plus1 40) and of add 1 (add 1 40), add 1 really being the exact same function as plus1).

Now I'm not sure whether you want to be able to pass (plus1 40) as the value for f and then somehow get 40 from that or whether you want to pass (add 1) and then somehow get back the 1, but both are impossible.

In the case of (plus1 40) you can't even pass that as the value for f. f is supposed to be a function, but (plus1 40) is an integer (41), not a function.

(add 1) on the other hand is a function and you can indeed pass it as the value for f. In fact I did so in my example. But what you can't do is get the value 1 back from it. I mean, imagine there was a way that you could do that. What should then happen if you passed plus1 instead of (add 1). What should you get back from that? There is no value captured in plus1, so there's really nothing to get back, but clearly plus1 is just as valid an argument to applyTwice as (add 1).

The only way this could possibly make sense is if partially applied function had a different type from normal functions, allowing you to define a function that accepts (add 1) as one argument, but not plus1. However that's not the case ML and there's really not much benefit to that. Having different types of functions would just make the type system more complicated and make it more difficult to define higher order functions (as they'd have to be able to deal with both types of function). Nor do I see the use case where this ability would even be helpful.