Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);

2 Answers

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

like image 139
Adam Mihalcin Avatar answered Sep 04 '26 18:09

Adam Mihalcin


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
like image 32
Sage Mitchell Avatar answered Sep 04 '26 18:09

Sage Mitchell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!