Finding max element in a list in SML - list

I am trying to find the the greatest value in a list using Standard ML. I need to use the given fold function:
fun fold f [] base = base
| fold f (x::xs) base = fold f xs (f x base);
Here is what i have so far:
fun max (x::xs) = fold (fn (a, b) => if a > b then a else 0) x (x::xs);
I have 0 in there because if the list is empty then I need to return 0;
This is only part of another function that I need to define, but I'm struggling with the fold part.

In your definition of the fold function, you require that the function f must take it's arguments in curry form, that is: f 1 1 instead of f(1,1).
As I understand, then your definition of the fold function is the right one. Thus you need to make proper changes to the anonymous function in the max function.
In SML, currying is actually just syntactic sugar. For example:
fun foo a b = a+b
would end up as (after desugaring):
val rec foo = fn a => fn b => a+b
It is also seen that the two functions has the same type:
- fun foo a b = a+b;
val foo = fn : int -> int -> int
- val rec foo = fn a => fn b => a+b;
val foo = fn : int -> int -> int
Thus the anonymous function must be define somewhat along the same lines.
Also you have mixed the arguments to fold. In the last part of the max function, you are giving the two last arguments in the reverse order.
The last problem is that your anonymous function returns 0. This screws with the invariant of you anonymous function and makes it fail in some cases. For example:
max [1,4,65,7,6];
Try to figure out why yourself.
If you really need to return 0 if the input list to max is empty, then you should pattern match that case. This also fixes the warning about "match nonexhaustive", and is the correct place to do it.
fun max [] = 0
| max (x::xs) = fold (fn a => fn b => if a > b then a else b) (x::xs) x;

Related

How can I write a function in OCaml that takes an integer list and return the element with maximum absolute value

I have tried to write code but this only returns max value and not the absolute.
let rec maxAbsolutenumber_L l =
match l with
|[] -> None
|x::_ -> x
|x::xs -> max x (max_number_list xs)
Imagine you had a function like max except it returns whichever of the two values has the largest absolute value. Seems like that would solve your problem.
You can start, then, by writing this function.
As a side comment, it is not legitimate to return None for some calls to a function and an integer value for other calls. They aren't the same type.
As another side comment, the second case of your match will match all nonempty lists. I think you want it to match only lists of length 1. The pattern for such a list is [x] (or you can use x :: [], which is equivalent).
Update
Here is the basic structure for defining a function that has another (helper) function inside:
let myfunc a b =
let helper x y =
(* Definition of helper *)
in
(* Definition of myfunc with calls to helper *)
Here's a concrete example, a function that returns the longest string in its input list:
let longest_string strings =
let max_string a b =
if String.length a >= String.length b then a else b
in
List.fold_left max_string "" strings
Here is an implementation of the usual max function, which might give you some ideas for writing similar functions:
let max a b =
if a >= b then a else b

Understanding the mechanics of fold_right

Problem:Define the function mapf whose first argument is a unary function, and second argument list. The result is a list of the function applied to each element of the argument list. Write a one-liner using fold_right, and not a recursive function.
Solution:
let mapf fn list = fold_right (fun h t -> fn h :: t) list []
I don't understand how that solves the problem because fold_right computes a function with the list arguments in a recursive way, so it returns a value and not a list. I neither understand what the following notation means:
fun h t -> fn h :: t
Your two questions are related. It's true that fold_right returns a value, but a list is a value!
The :: operator adds a new element to the beginning of a list. So the value computed by this application of fold_right is indeed a list.
Another way to think of this might be as follows. If you use fold_right with the + operator you compute a value like so:
fold_right (+) [1; 2; 3] 0 =>
1 + 2 + 3 + 0 =>
6
If you use fold_right with the :: operator, you compute a value like so:
fold_right (::) [1; 2; 3] [] =>
1 :: 2 :: 3 :: [] =>
[1; 2; 3]
This isn't theoretical, it works exactly like this in the REPL:
# List.fold_right (+) [1; 2; 3] 0;;
- : int = 6
# List.fold_right (fun a b -> a :: b) [1; 2; 3] [];;
- : int list = [1; 2; 3]
(You need to write fun a b -> a :: b because the :: notation can't actuallly be used as a stand-alone function. Unfortunately.)
Note that it's completely legitimate to write a list using the :: operator yourself:
# 1 :: 2 :: 3 :: [];;
- : int list = [1; 2; 3]
Update
First, fun x y -> expr is the notation for a "lambda" in OCaml, i.e., for a function literal.
The function fun h t -> fn h :: t takes two values h and t. It applies the function fn to h, and returns a new list with this new value at the front of t.
From a typing standpoint, the value h must be the right type to pass to fn, and fn must return a value of the right type to be in the list t.
You could parenthesize it like this: fun h t -> (fn h) :: t, if that makes it clearer.
The function fun a b -> a :: b is similar except that it just puts a directly onto the list b. It doesn't apply any function. In essence, it does just what the :: operator does.
From a typing standpoint, a has to be the right type to be an element of the list b.
Update 2
If you're trying to understand what a lambda is, one way of looking at it is that it's just a handy way to write a function that's reasonably small. You can easily write your given code without the lambda:
let mapf fn list =
let helper h t = fn h :: t in
List.fold_right helper list []
Instead of a lambda, this version has a locally declared function named helper.
Another way of looking at it is that all functions are lambdas. The idiomatic way of writing a function:
let f x y = x + y
is just a handy abbreviation for a version with an explicit lambda:
let f = fun x y -> x + y
So, really, a lambda isn't a special kind of function. It's exactly like any other function. It's just a notational choice.

Why am I getting "unbound variable or constructor" in my SML program

I have written a method to return the first element in a list that satisfies a function (passed in via currying). The function returns NONE or SOME depending on whether or not the element satisfies a condition. I'm using Pattern Matching
However, I'm getting the dreaded error:
Error: unbound variable or constructor: my_function
I'm new to SML and one of the hardest things I find is understanding the error messages. From previous experience with the message, I would think the problem is that my_function never returns, but I'm having trouble seeing the logic problem here. Can someone take a quick look and tell me the problem? Is the problem that I'm raising an error when there is no element that satisfies the input function f?
I'm interested in what's wrong and perhaps more importantly, is there any way to get more information when you see this sort of error?
val my_function = fn f => fn lst => (* Notice currying *)
case lst of
[] => raise NoAnswer (* Get here is nothing in lst saf
| x::xs => case f(x) of NONE => ( my_function f xs)
| SOME y => x
val test = my_function(fn x => if x < 3 then SOME x else NONE) [1,2,3,4] = 2
Thanks, Dave
If you declare a function with the val keyword, the function can't be defined recursively. Hence, the problem is here:
... NONE => ( my_function f xs) ...
You can say that you want the function to be defined recursively by adding the rec keyword to the declaration.
val rec my_function = fn f => fn list => ...
Alternatively, the fun keyword is syntactic sugar for val rec. fun also includes nice syntactic sugar for currying:
fun my_function f lst = (* This is equivalent to your first line *)
Sometimes you still want to use just the val keyword and not val rec. For instance,
val f = fn x => x + 3
val f = fn y => f y + 4 (* f here refers to the previous declaration of f *)

A curry function that executes another function n times

I'm solving an old exam to practice SML. One task I found interesting was: Write a function repeat that executes another function with the signature 'a -> 'a.
I assumed the requested function is a curry function and used the o-Operator:
fun repeat (1, f: 'a->'a) = f
| repeat (n, f: 'a->'a) = f o repeat (n-1, f);
However, the o operator was not formally introduced in out course, and I wonder how I could write this without it?
Not the less verbose, but in some way, the most explicit, then after, the less verbose, with explanations.
A curried function is a function getting a single argument. If an expression has more arguments, then there are as many nested functions. The first outer level function gets an argument, and is made of an inner level function which may it‑self be made of an inner function, and so on. Any of this inner level function may be returned, not just the innermost, as explained later (this is a kind of “partial evaluation”). An inner function is “specialized” with the arguments (formally, the arguments are bound in a closure) of the outer functions.
We know there are at least a function argument f and integer argument counter. There needs to be an argument seed also, to invoke the function f the first time.
The order of nesting may be arbitrary or specified. If not specified, I personally prefer to put the least varying arguments on the outer‑scope and the most varying in the inner‑scope. Here, I would say it is, from least to most varying: f, counter seed.
This is already enough to suggest the beginning of a template:
val repeat: ('a -> 'a) -> int -> 'a -> 'a =
fn f: 'a -> 'a =>
fn count: int =>
fn seed: 'a =>
…
We already implemented the ('a -> 'a) -> int -> 'a part of the signature. Remains the last -> 'a which means an 'a is to be returned, and it will be evaluated by an inner loop.
A loop may be something of this form (in pseudo‑code):
val rec loop = fn i =>
if condition-to-stop
then return-something-or-`()`
else loop (i + 1) or (i - 1)
If the loop is to compute something, it will need an extra argument acting as an accumulator, and will return that accumulator as its final result.
Implementing the loop and putting it inside the curried function template above, we get:
val repeat: ('a -> 'a) -> int -> 'a -> 'a =
fn f: 'a -> 'a =>
fn count: int =>
fn seed: 'a =>
let
val rec loop = fn (counter, x) =>
if counter <= 0 then x
else loop (counter - 1, f x)
in
loop (count, seed)
end
Do you understand the let … in … end construct here?
Note the guard on counter may use a pattern as you did, but as SML's integer may be negative (there is no strict natural in SML), that's safer to catch this case too, thus the if … then … else instead of a pattern matching. Mileage may vary on that point, but that's not the question's focus.
The same as above, using fun instead of val rec:
fun repeat (f: 'a -> 'a) (count: int) (seed: 'a): 'a =
let
fun loop (counter, x) =
if counter <= 0 then x
else loop (counter - 1, f x)
in
loop (count, seed)
end
Note for repeat the arguments are not separated by a , (neither a *). This is the way to write a curried function using fun (on the contrary, loop is not curried). Compare it with the prior val version of the same function. If no type is specified and only names, the parenthesis can be omitted.
A test function to be used as the f argument:
val appendAnX = fn s: string => s ^ "x"
The test:
val () = print (repeat appendAnX 5 "Blah:")
Curried function are more abstract than function getting a tuple (which is formally a single argument, thus makes a curried function too, but that's another story and a bit cheating), as the outer function(s) may be partially applied:
This is a partial application, leaving the last argument, seed, unbound:
val repeatAppendAnXThreeTimes = repeat appendAnX 3
Then this function may be applied specifiying only this seed:
val () = print (repeatAppendAnXThreeTimes "Blah:")
Similarly, both counter and seed may be left free:
val repeatAppendAnX = repeat appendAnX
val () = print (repeatAppendAnX 4 "Blah:")
Another way of defining repeatAppendAnXThreeTimes. Compare it to its other definition above:
val repeatAppendAnXThreeTimes = repeatAppendAnX 3
val () = print (repeatAppendAnXThreeTimes "Blah:")

Alonzo Church numerals in SML

I have an assignment that involves making church numerals in SML. I've looked around and just can't find what I'm doing wrong. The goal is to make a function that takes an int and returns a church numeral, defined as datatype 'a numeral = Num of ('a -> 'a) -> 'a -> 'a (which is predefined by my teacher). Then to make a second function that takes a church numeral and returns an int.
I saw a previous post with the code:
val ZERO = C(fn (f,x) => x)
fun subCreate 0 (f,x) = x
| subCreate n (f,x) = f (subCreate (n-1) (f,x))
fun create n = C(fn (f,x) => subCreate n (f,x));
fun churchToInt (c, cn) = cn ((fn x => x+1), 0) 0;
but this does not work, and gives the error type vars not generalized because of value restriction are instantiated to dummy types.
When I used the code:
val zero = fn s => fn x => x;
(to define a zero) and then
val next = fn n => fn s => fn x => (f ((n s) x));
(just to do a test to see if I could increment zero, before setting up an iterative or recursive function), I got the same error. I've spent hours on this problem, unable to produce a church numeral. Can someone point me in the right direction?
I think you are running into the "value polymorphism" in SML'97. Here is a very long section of documentation discussing it.
One workaround is, whenever you have an expression which causes this problem, e.g. next zero, wrap a function around it, e.g. fn x => next zero x.
Another thing I think you could do is instead of evaluating definitions at the top level in the interpreter, wrap the definition and all the code that uses it into local scope (e.g. inside let ... in ... end) or into functions.