147pm
147pm

Reputation: 2239

SML functions as values

I'm experimenting with this in SML

- val p = (fn (x,y) => x + y, fn (x,y) => x - y)
val p = (fn,fn) : (int * int -> int) * (int * int -> int)

But I may only evaluate it one at a time

- #1(p)(3,2)
5

or

- #2(p)(3,2)
1

Why can I not do both?

- (p)(3,2)
Error: operator is not a function [tycon mismatch]...

What quasi-lambda calculus form would I need to have it return a 2-tuple, the first position from x+y lambda function, and the second from x-y lambda function? At first glance, that's what it looks like it will do. In general, I'm lost as to what a variable and a function is in this example.

Upvotes: 0

Views: 311

Answers (2)

Andreas Rossberg
Andreas Rossberg

Reputation: 36118

I am not sure what you are asking. A function is a function, a pair is a pair. A pair of functions is not a function, so it cannot be applied.

However, you can convert a pair of functions into a function on pairs by defining a form of map function on pairs, similar to map for lists:

fun mapPair (f, g) (x, y) = (f x, g y)

With that, you can do:

mapPair (p) (2, 3)

Edit: The above is just shorthand for a curried function, i.e., a function returning a function:

fun mapPair (f, g) = fn (x, y) => (f x, g y)

or equivalently:

val mapPair = fn (f, g) => fn (x, y) => (f x, g y)

Upvotes: 2

molbdnilo
molbdnilo

Reputation: 66459

fn (x,y) => x + y and fn (x,y) => x - y are functions; p is a pair of functions; #1 p and #2 p are functions; a pair is not a function.

If you want an anonymous function (I'm assuming that's what "quasi-lambda calculus form" means), it would look like this

fn (f, g) => fn x => (f x, g x)

that is, first take a pair of functions, then something, then apply both functions to the something.

- (fn (f,g) => fn x => (f x, g x)) p (3,2);
val it = (5,1) : int * int

or, if you're determined on using selectors instead of pattern matching:

- (fn fns => fn x => (#1 fns x, #2 fns x)) p (3,2);
val it = (5,1) : int * int

Upvotes: 2

Related Questions