Reputation: 21
I just spent an embarrassing amount of time figuring out that if you're passing a parameterized datatype into a higher-order function in SML, it needs to be in brackets ()
; so, for example:
fun f1 p = f2 p
will work when called like this (for example): f1(Datatype(parameter))
but will not work if called like f1 Datatype(parameter)
. I'm sure there's a very simple reason why, but I'm not quite clear. Is it something like, the datatype and parameter are "seen" as 2 things by the function if not in brackets? Thanks!
Upvotes: 0
Views: 56
Reputation: 36536
It's important to realize how functions work in SML. Functions take a single argument, and return a single value. This is very easy to understand but it's very often practically necessary for a function to take more than one value as input. There are two ways of achieving this:
Tuples
A function can take one value that contains multiple values in the form of a tuple. This is very common in SML. Consider for instance:
fun add (x, y) = x + y
Here (x, y)
is a tuple inferred to be composed of two int
s.
Currying
A function takes one argument and returns one value. But functions are values in SML, so a function can return a function.
fun add x = fn y => x + y
Or just:
fun add x y = x + y
This is common in OCaml, but less common in SML.
Function Application
Function application in SML takes the form of functionName argument
. When a tuple is involved, it looks like: functionName (arg1, arg2)
. But the space can be elided: functionName(arg1, arg2)
.
Even when tuples are not involved, we can put parentheses around any value. So calling a function with a single argument can look like: functionName argument
, functionName (argument)
, or functionName(argument)
.
Your Question
f1(Datatype(parameter))
This parses the way you expect.
f1 Datatype(parameter)
This parses as f1 Datatype parameter
, which is a curried function f1
applied to the arguments Datatype
and parameter
.
Upvotes: 2