Reputation:
I'm still a bit confused about currying -
I've got an implementation of map in SML, is this considered as a curried function?
fun mymap f xs = List.foldr (fn (x, l) => (f x)::l) [] xs;
Or do I need to be more explicit about enforcing the single parameter passing?
fun mymap f = (fn xs => List.foldr (fn (x, l) => (f x)::l) [] xs);
Upvotes: 3
Views: 340
Reputation: 1583
Adam already answered this, but I want to teach you to fish.
Each time you type a function into an SML interpreter, you'll get a response with the function's type signature. Here's the first one:
- fun mymap f xs = List.foldr (fn (x, l) => (f x)::l) [] xs;
val mymap = fn : ('a -> 'b) -> 'a list -> 'b list
And here's the second one:
- fun mymap f = (fn xs => List.foldr (fn (x, l) => (f x)::l) [] xs);
val mymap = fn : ('a -> 'b) -> 'a list -> 'b list
The first thing we notice is they have the same type signature, which is consistent with the claim that the second is a desugared form of the first.
According to the signature, mymap
takes a function which maps from one type to another. Let's experiment using Int.toString
:
- mymap Int.toString;
val it = fn : int list -> string list
We've just done a partial application of the mymap
function, which is only possible because mymap
is a curried function.
For contrast, let's see what happens with a version of mymap
that isn't curried.
- fun mymapUncurried (f,xs) = List.foldr (fn (x, l) => (f x)::l) [] xs;
val mymapUncurried = fn : ('a -> 'b) * 'a list -> 'b list
This is the same as your first function, except the arguments are enclosed in a tuple. As a result, the type signature is also different (see the *
?). mymapUncurried
takes a 2-tuple whose first element has type ('a -> 'b)
and whose second argument has type 'a list
. Now partial application doesn't work:
- mymapUncurried Int.toString;
stdIn:9.1-9.28 Error: operator and operand don't agree [tycon mismatch]
operator domain: ('Z -> 'Y) * 'Z list
operand: int -> string
in expression:
mymapUncurried Int.toString
However, full application does work. Just don't forget to pass the arguments as a tuple:
- mymapUncurried (Int.toString, [1,2,3]);
val it = ["1","2","3"] : string list
Upvotes: 2
Reputation: 14458
Yes, both functions are curried. In fact, the first function is shorthand for the second function.
Upvotes: 4