views:

133

answers:

2

For example, instead of

- op =;
val it = fn : ''a * ''a -> bool

I would rather have

- op =;
val it = fn : ''a -> ''a -> bool

for use in

val x = getX()
val l = getList()
val l' = if List.exists ((op =) x) l then l else x::l

Obviously I can do this on my own, for example,

val l' = if List.exists (fn y => x = y) l then l else x::l

but I want to make sure I'm not missing a more elegant way.

+2  A: 

My knowledge of SML is scant, but I looked through the Ullman book and couldn't find an easy way to convert a function that accepts a tuple to a curried function. They have two different signatures and aren't directly compatible with one another.

I think you're going to have to roll your own.

Or switch to Haskell.

Edit: I've thought about it, and now know why one isn't the same as the other. In SML, nearly all of the functions you're used to actually accept only one parameter. It just so happens that most of the time you're actually passing it a tuple with more than one element. Still, a tuple is a single value and is treated as such by the function. You can't pass such function a partial tuple. It's either the whole tuple or nothing.

Any function that accepts more than one parameter is, by definition, curried. When you define a function that accepts multiple parameters (as opposed to a single tuple with multiple elements), you can partially apply it and use its return value as the argument to another function.

Barry Brown
You state "any function that accepts more than one parameter is, by definition, curried". Well, I think a function of type ('a -> 'b -> 'c) also accepts just a single parameter (the 'a), it just happens to return another function which is of type ('b -> 'c). This is due to the "->" operator being right-associative: ('a -> 'b -> 'c) = ('a -> ('b -> 'c)). Partial application is then just a consequence of this. Function application is left-associative, so that (myFun arg1 arg2 arg3) = (((myFun arg1) arg2) arg3).
harms
+3  A: 

You could write a helper function that curries a function:

fun curry f x y = f (x, y)

Then you can do something like

val curried_equals = curry (op =)
val l' = if List.exists (curried_equals x) l then l else x::l
newacct