How many arguments does the map function take in SML? - functional-programming

I'm trying to learn SML and some of my professor notes talk about the map function "which has type ('a -> 'b) -> ('a list -> 'b list)." He goes on to explain that this means that "you give me a function that transforms 'a s into 'b s...".
However, he the implementation looks like:
fun map f [] = []
| map f (a::l) = (f a)::(map f l)
This appears to me that it's taking the equivalent of 2 arguments (I know that everything in sml technically only takes one argument, but using tuples or currying it can look like 2). It appears that it's taking a function and a list. However, the explanation above makes it sound like it's only taking a function. What am I missing?

As you said yourself SML doesn't really have polyadic functions, it only simulates using tuples or currying. In this case map is a curried function. The reason that your professors statement makes sense is that a curried function is simply a function that takes one argument and returns a function that takes the next argument.
One way to see this is to rewrite fun in terms of val. In general fun f x y = bla is equivalent to val rec f = fn x => fn y => bla. So the definition of map can equivalently be written like this:
val rec map = fn f => fn as => case as of
[] => []
| (a::l) => (f a)::(map f l)
Looking at that definition it's clear that the first fn creates a function that returns another function (the second fn).
We can also see that this is the case by observing that it is legal to call map with only one argument and the result is a function:
val my_map = map my_function
val mapped_list = my_map my_list
In the above my_map my_list is equivalent to map my_function my_list. This shows us that calling map my_function my_list (which is equivalent to (map my_function) my_list due to function application being left-associative) simply calls map with the argument my_function and then calls the function retuned by map with my_list as its argument.
That's what currying is all about.

Related

Is recursive partial function application possible in F#?

I am working with the function 2x^2+y^2, defined in my code as:
fx = fun x y -> (2 * (pown x 2)) + (pown y 2)
and I was wondering if it was possible to apply the x and y components recursively?
Currently, if I do, say,
let f1 = fx 0.0 //<fun:it#9-2>
let f2 = f1 2.0 //4.0
then this works as expected. However, if I were to give my function a and b parameters to indicate some interval, intellisense throws a fit.
let ab = [0.0; 2.0]
let result =
let rec getres fn lst =
match lst with
| hd :: tl ->
let f1 = fn hd
getres f1 tl // <- error here
| [] -> fn
getres fx ab
then intellisense on f1 gives me an error:
Type mismatch. Expecting a
"a -> 'b'
but given a
"b'.
The types "a' and "b -> 'a' cannot be unified
I want to be able to recursively apply any number of parameters from a list of parameters (e.g. my ab list in the example above) to a function that I supply to my expression, in the form of fun x1 x2 x3 … xn -> x1 + x2 + x3 + … + xn. Is this possible?
I think you may need to specify a signature for the function argument of getres. Based on the error message the compiler is inferring that fn takes a single argument and returns a result. So on the error line f1 is not a function but a value. Ie. there is no currying happening.
But that won't handle the final case where you want to execute the function rather than performing partial application. You may need an extra level of indirection to handle this. (In other .NET languages one would need to use reflection for this – which allows a function to be called passing an array of parameters – it may not be possible in a strongly typed .NET language to handle this without reflection.)
Additional (to summarise the comments below):
Consider the required signature of getres. If fn is a function of two arguments (ie. 'a -> 'a -> 'b) then getres has a signature:
('a -> 'a -> 'b) -> list 'a -> ('a -> 'b`)
for the first call.
But when that instance of getres makes its recursive call it needs to be a function taking a single argument, ie. its signature needs to be:
('a -> 'b) -> list 'a -> 'b`
This is not possible with a single F# function.
It is possible with a .NET function (ie. a class member), but only if each "level" is separately written (ie. hard coding the maximum number of arguments). (Compare how System.Func<T1, TRes>, System.Func<T1, T2, TRes> are defined in the .NET runtime.)
(This is the kind of thing that dynamic languages can easily handle, but strongly typed languages need a very sophisticated type system underlying it to achieve.)

SMLNJ powerset function

I am trying to print the size of a list created from below power set function
fun add x ys = x :: ys;
fun powerset ([]) = [[]]
| powerset (x::xr) = powerset xr # map (add x) (powerset xr) ;
val it = [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]] : int list list;
I have the list size function
fun size xs = (foldr op+ 0 o map (fn x => 1)) xs;
I couldnt able to merge these two functions and get the result like
I need something like this:
[(0,[]),(1,[3]),(1,[2]),(2,[2,3]),(1,[1]),(2,[1,3]),(2,[1,2]),(3,[1,2,3])]
Could anyone please help me with this?
You can get the length of a list using the built-in List.length.
You seem to forget to mention that you have the constraint that you can only use higher-order functions. (I am guessing you have this constraint because others these days are asking how to write powerset functions with this constraint, and using foldr to count, like you do, seems a little constructed.)
Your example indicates that you are trying to count each list in a list of lists, and not just the length of one list. For that you'd want to map the counting function across your list of lists. But that'd just give you a list of lengths, and your desired output seems to be a list of tuples containing both the length and the actual list.
Here are some hints:
You might as well use foldl rather than foldr since addition is associative.
You don't need to first map (fn x => 1) - this adds an unnecessary iteration of the list. You're probably doing this because folding seems complicated and you only just managed to write foldr op+ 0. This is symptomatic of not having understood the first argument of fold.
Try, instead of op+, to write the fold expression using an anonymous function:
fun size L = foldl (fn (x, acc) => ...) 0 L
Compare this to op+ which, if written like an anonymous function, would look like:
fn (x, y) => x + y
Folding with op+ carries some very implicit uses of the + operator: You want to discard one operand (since not its value but its presence counts) and use the other one as an accumulating variable (which is better understood by calling it acc rather than y).
If you're unsure what I mean about accumulating variable, consider this recursive version of size:
fun size L =
let fun sizeHelper ([], acc) = acc
| sizeHelper (x::xs, acc) = sizeHelper (xs, 1+acc)
in sizeHelper (L, 0) end
Its helper function has an extra argument for carrying a result through recursive calls. This makes the function tail-recursive, and folding is one generalisation of this technique; the second argument to fold's helper function (given as an argument) is the accumulating variable. (The first argument to fold's helper function is a single argument rather than a list, unlike the explicitly recursive version of size above.)
Given your size function (aka List.length), you're only a third of the way, since
size [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]
gives you 8 and not [(0,[]),(1,[3]),(1,[2]),(2,[2,3]),...)]
So you need to write another function that (a) applies size to each element, which would give you [0,1,1,2,...], and (b) somehow combine that with the input list [[],[3],[2],[2,3],...]. You could do that either in two steps using zip/map, or in one step using only foldr.
Try and write a foldr expression that does nothing to an input list L:
foldr (fn (x, acc) => ...) [] L
(Like with op+, doing op:: instead of writing an anonymous function would be cheating.)
Then think of each x as a list.

Lists of Functions and their execution Erlang

Is it possible to create and send a list of functions as an argument to another function, and then have some functions within this list call other functions in this list?
For example, I want a function that works on a list passed as an argument, and then performs the first function in the list of functions on this list of numbers, and if that function makes calls to other functions within that list, they can be retrieved and used.
e.g.: deviation(Numbers, Functions) -> %Functions = [fun master/1, fun avg/1, fun meanroots/1]
Master calls avg, then passes that result into meanroots, etc. but at the end of the call chain the master is the one that will return a value.
I'd like to know if this is functionally possible, whether within OTP alone or using NIFs, and if there are samples of implementation to look at.
How would your function know whether one of the functions in the list called another function in the list? I think your question is worded confusingly.
You could create a function to chain the results through a series of functions:
chain(Nums, []) -> Nums;
chain(Nums, [H | T]) -> chain(H(Nums), T).
which could be done with a standard function:
lists:foldl(fun (F, V) -> F(V) end, Nums, Funcs)
Of course you can:
1> F1 = fun(A) -> A*A end.
#Fun<erl_eval.6.50752066>
2> F2 = fun(A) -> A+A end.
#Fun<erl_eval.6.50752066>
3> F3 = fun(A) -> A*A+A end.
#Fun<erl_eval.6.50752066>
4> Funs = [F1, F2, F3].
[#Fun<erl_eval.6.50752066>,#Fun<erl_eval.6.50752066>,
#Fun<erl_eval.6.50752066>]
5> [F(X) || X <- [1,2,3], F <- Funs].
[1,2,2,4,4,6,9,6,12]
You could create tagged tuples with functions, e.g. {tag1, F1} (where F1 is defined as above), pass them to functions and do with them all sort of stuff you would normally do with any other variable in Erlang.

Standard ML: Unsure of Type of Higher Order Function

I'm reading Harper's book, Intro to Standard ML, and am a bit confused on section 11.3, Returning Functions.
1) He defines a function that creates constant functions. He writes:
"Given a value k, the application constantly k yields a function that yields k whenever it is applied. Here's a definition of constantly:
val constantly = fn k => (fn a => k)
The function constantly has type 'a -> ('b -> 'a)." This makes sense to me: you supply a value of type 'a and it returns a function that always returns that value (of type 'a), regardless of the input (of type 'b, which may or may not be same as type 'a).
But then he says we can also define this function as:
fun constantly k a = k
This just looks like a function that takes two arguments and returns the first...but not a function that returns another function...
What am I missing?
2) A little later, Harper discusses a map function. I understand the basic map function. He then talks about a map function that will let us apply the passed-in function to many lists (instead of calling our original map function several times with the same passed-in function for each call). He writes:
fun map' f nil = nil
| map' f (h::t) = (f h) :: (map' f t)
"The function map so defined has type ('a -> 'b) -> 'a list -> 'b list. It takes a function of type 'a -> 'b as argument and yields another function of type 'a list -> 'b list as result."
I'm pretty lost here as it looks like map' just applies f to all of the elements in a list and returns the resulting list. So I would have thought it would be of type:
('a -> 'b) * 'a list -> 'b list
Where am I going wrong?
Thanks for the help,
bclayman
Both of your questions arise from a lack of clarity about what arguments to a function actually are. In SML, every function (recall that functions are values) takes precisely one argument. That argument may be a tuple (of type 'a * 'b but it is still a single argument (that needs to be destructured).
In SML, fun f x1 x2 ... = T is syntactic sugar for val rec f = fn x1 => fn x2 => ... => T. So constantly k evaluates to fn a => k.
Whether you give map the type ('a -> 'b) * 'a list -> 'b list or ('a -> 'b) -> 'a list -> 'b list is a library design issue, but the effect is the same. They do the same thing, though the first takes a tuple of a function and a list, while the second takes the function first and returns a function from lists to lists. This is called "currying" in the programming languages literature. (The tuple version is "uncurried", the other is "curried".)
The magic word is "currying": https://en.wikipedia.org/wiki/Currying
In ML (as well as Haskell) function application binds tighter than any other operator. Thus constantly k a parses as (constantly k) a. constantly k binds to a function. To understand what function, you can mentally think of the definition
fun constantly k a = k
as being equivalent to
fun (constantly k) a = k
This says that (constantly k) is the function that maps any a to k.
Thus its type is 'a -> ('b -> 'a), as claimed in the text.
There is nothing illegal about defining constantly via
fun constantly (k,a) = k
It will have the type 'a * 'b -> 'a which you seem to expect, but calling it "constantly" then is a bit weird since it wouldn't be a constant function.
I'm sure that Harper will get to it sooner or later. Such functions are heavily used in both ML and Haskell (especially Haskell).

What happens underneath append function?

I got an implementation for append function in OCaml, but it seems confused to me
let rec append = function
| [] -> fun y -> y
| h :: t -> fun y -> h :: (append t y)
What is the purpose of the fun y in this case ?
The type of append is 'a list -> 'a list -> 'a list. You can look at this as a function that takes two lists and returns a list. But (as is idiomatic in OCaml) the function is defined using currying. So at the basic level, append takes a first list and returns a function of type 'a list -> 'a list. The returned function takes the second list and prefixes the first list to it (returning the result).
The value fun y -> y is the function that append returns when the first list is empty. If you think about it, this makes sense. If the first list is empty, the second list will be returned unchanged. In other words, the returned function is no different at all from an identity function (specialized for applying to lists).
The second case returns the value fun y -> h :: (append t y). This is similar, but a little more complicated. The returned function needs to do some actual appending. It does this by (recursively) appending the supplied second list (y) to the tail of the first list (t), then adding the head of the first list (h) to the front of that.
If you don't like the fun, you can rewrite the function like this
let rec append x y = match x with
| [] -> y
| h :: t -> h :: append t y

Resources