vesii
vesii

Reputation: 3128

What does it mean functions in SML have only one argument?

So I read that every function in SML has one argument and one result. But I saw examples like:

fun foo x y = x + y;
fun goo x y z = 5;

Those examples make me think that they get more than one argument. The signatures:

val foo = fn : int -> int -> int
val goo = fn : 'a -> 'b -> 'c -> int

The only possible explanation that I can think of, is "syntactic sugar", although I'm not sure. What could be the explanation to this?

Upvotes: 1

Views: 196

Answers (2)

Rincewind
Rincewind

Reputation: 317

There is indeed some syntactic sugar involved. If I remember correctly,

fun foo x y = x + y

is just syntactic sugar for

val rec foo = fn x => (fn y => x + y)

So this definition does in fact define a function foo that takes a single argument x of type int and returns a function of type int -> int. So the function application foo 5 returns a function:

fn y => 5 + y

This returned function can of course also take an argument. This is what looks like a second argument. But notice that this argument is not an argument of foo but an argument of the result we get when applying foo to its single argument.

Upvotes: 1

Carcigenicate
Carcigenicate

Reputation: 45740

Although your examples seem to take multiple arguments, they actually take one argument at a time.

foo 1 returns a function that takes y as an argument, then when you apply y, the function evaluates.

goo 1 returns a function that takes y, which when given returns a function that takes z, which when given allows the function to evaluate.

This allows you to easily partially apply a function by giving it less arguments than it asks for:

val f = foo 1 (* Returns a function *)
val returnVal = f 2 (* Both arguments were given, so the function is fully applied and evaluates *)

When combined with functions like map or List.filter, you can make nice readable code:

val keepNegatives = List.filter isNeg

keepNegatives [~1, ~2, 1, ~3]
> [~1, ~2, ~3]

Where isNeg is a predicate that checks if a number is negative, and List.filter is a function that keeps elements from a collection that satisfy the given predicate.

Upvotes: 3

Related Questions