Reputation: 25
To my understanding, curried functions should always return a function. However, in the code below, I believe this function returns a list. But when I check the type, it looks like a curried function.
fun zipWith f xs ys =
case (xs,ys) of
([],_) => []
| (_,[]) => []
| (x::xs',y::ys') => (f(x,y)) :: zipWith f xs' ys'
The type:
val zipWith = fn : ('a * 'b -> 'c) -> 'a list -> 'b list -> 'c list.
Could someone explain the type and how currying works in this function. Any help is appreciated!
Upvotes: 0
Views: 77
Reputation: 66371
It is curried - you don't need to pass all the arguments at once, but it produces a list when all of them have "arrived".
It's common to write all the curried parameters on the left-hand side if the function is not meant to be primarily a "function-creating" function.
The definition looks more like the type if you write it on the (equivalent) form
fun zipWith f = fn xs =>
fn ys =>
case (xs,ys) of
([],_) => []
| (_,[]) => []
| (x::xs',y::ys') => (f(x,y)) :: ((zipWith f) xs') ys'
Example of the "curriedness":
- val add = zipWith (op +);
val add = fn : int list -> int list -> int list
- val add_123 = add [1,2,3];
val add_123 = fn : int list -> int list
- add_123 [4,5,6];
val it = [5,7,9] : int list
Upvotes: 2
Reputation: 370112
fun f arg1 ... argN = exp
is a syntactic shortcut for val rec f = fn arg1 => ... => fn argN => exp
. So in your case we have:
val rec zipWith = fn f => fn xs => fn ys =>
case (xs, ys) of
...
So zipWith
is a function that, when given an argument f
, returns another function that, when given an argument xs
, ... and so on. In other words, it's curried.
Upvotes: 7