akhil
akhil

Reputation: 11

SML - Passing NONE or SOME as argument

I have just started on SML and I am having trouble trying to pass NONE/SOME as parameters to a function.

fun fx (SOME x) (SOME y) f = f x y
    | fx (SOME x) (NONE) f = NONE
    | fx (NONE) (SOME y) f = NONE
    | fx (NONE) (NONE) f = NONE;

fun add x y = x + y;

fx (SOME 2) (SOME 4) add;

What I am trying to do is to add two numbers only if neither values are NONE. But I get the following error:

Error: operator and operand do not agree [tycon mismatch]
  operator domain: int -> int -> 'Z option
  operand:         int -> int -> int
  in expression:
    ((fx (SOME 2)) (SOME 4)) add

If remove the cases for NONE, i.e:

fun fx (SOME x) (SOME y) f = f x y

Then it works alright. I don't know where exactly am I making a mistake. f parameter is not optional, yet it is treating as one.

Upvotes: 1

Views: 143

Answers (2)

molbdnilo
molbdnilo

Reputation: 66371

You've already answered the "how", so I will try and explain the "why".

Look at the type of fx in the REPL:

val fx = fn : 'a option -> 'b option -> ('a -> 'b -> 'c option) -> 'c option

It produces a 'c option (it is known from your NONE cases that the result is an option type).
(Note that 'a -> 'b -> 'c option is 'a -> ('b -> ('c option)), not ('a -> 'b -> 'c) option.)

Since your first case is f x y, that must produce an option type - and add doesn't.

This is what the error message is trying to say; since SOME 2 and SOME 4 are int options, fx (SOME 2) (SOME 4) has the type (int -> int -> int option) -> int option (the "operator domain" is int -> int -> int option), but add is an int -> int -> int.
(The use of the word "operator" here is a bit confusing. You get used to it.)

If you want the more generic type 'a option -> 'b option -> ('a -> 'b -> 'c) -> 'c option, you need to wrap the result (as you've found):

fun fx (SOME x) (SOME y) f = SOME (f x y)

Upvotes: 1

akhil
akhil

Reputation: 11

Like Nalin pointed out in the comments, I had to redefine the method, just not on add but on fx actually.

fun fx (SOME x) (SOME y) f = SOME (f x y)

Upvotes: 0

Related Questions