user595334
user595334

Reputation:

Is this considered a curried function?

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

Answers (2)

Sage Mitchell
Sage Mitchell

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

Adam Mihalcin
Adam Mihalcin

Reputation: 14458

Yes, both functions are curried. In fact, the first function is shorthand for the second function.

Upvotes: 4

Related Questions