I need to write a very simple function in SML. It should check if the value 'elem' is greater than any value of the field 'f1' in the list 'L'. The list 'L' contains 3 fields - 'f1','f2','f3'. The function should return 1 if the statement 'elem>f1' is true for any of the members of the list 'L'. Otherwise, the function should return 0. For instance:
L =
f1 f2 f3
1 4 6
2 1 2
3 4 8
8 5 9
elem = 3
fun check(L: myList, elem: int): int =
let
val counter = ref 0
val counter_end = length L
in
while (!counter <= counter_end) do
let val f1 = List.nth(L,counter)
in
if elem > f1 then 1 else 0
end
counter := !counter + 1
end
I don't know how to get the field 'f1' from the list 'L'. Any ideas are HIGHLY appreciated.
In SML (and functional languages in general), you'll typically want to rely on recursion rather than imperative constructs like loops.
I'm a bit rusty in SML, but here's one way to define the function
fun check elem [] = 0
| check elem ((f1,f2,f3)::tl) = if elem > f1 then 1 else check elem tl;
It can then be called like this:
(* define a list to scan *)
val L = [(1,4,6),(2,1,2),(3,4,8),(8,5,9)];
(* call the function on our list *)
check 3 L;
The function is defined recursively, using pattern matching: The first line says that if the function is called on an empty list, the result is zero.
The second line says that if it is called on a list, where the first element is the tuple (f1,f2,f3), then the result is 1 if elem > f1, and otherwise, it's the result of invoking the function recursively on the tail of the list
Also note that I omitted the type specifiers. You rarely need them, because the language infers the types automatically. The compiler already knows which types can be safely used with the code you wrote, so why bother telling it what types you think the arguments are going to be?
Use a recursive function instead of using a loop. (And it would probably make more sense to use a boolean return instead of an integer.)
Easiest way to extract the fields is via pattern matching in the argument list. Assuming your three fields are in a tuple, something like this:
fun check((f1,f2,f3)::L: myList, elem: int)
Related
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
I want to convert a sequence to a list using List.init. I want at each step to retrieve the i th value of s.
let to_list s =
let n = length s in
List.init n
(fun _i ->
match s () with
| Nil -> assert false
| Cons (a, sr) -> a)
This is giving me a list initialized with the first element of s only. Is it possible in OCaml to initialize the list with all the values of s?
It may help to study the definition of List.init.
There are two variations depending on the size of the list: a tail recursive one, init_tailrec_aux, whose result is in reverse order, and a basic one, init_aux. They have identical results, so we need only look at init_aux:
let rec init_aux i n f =
if i >= n then []
else
let r = f i in
r :: init_aux (i+1) n f
This function recursively increments a counter i until it reaches a limit n. For each value of the counter that is strictly less than the limit, it adds the value given by f i to the head of the list being produced.
The question now is, what does your anonymous function do when called with different values of i?:
let f_anon =
(fun _i -> match s () with
|Nil -> assert false
|Cons(a, sr) -> a)
Regardless of _i, it always gives the head of the list produced by s (), and if s () always returns the same list, then f_anon 0 = f_anon 1 = f_anon 2 = f_anon 3 = hd (s ()).
Jeffrey Scofield's answer describes a technique for giving a different value at each _i, and I agree with his suggestion that List.init is not the best solution for this problem.
The essence of the problem is that you're not saving sr, which would let you retrieve the next element of the sequence.
However, the slightly larger problem is that List.init passes only an int as an argument to the initialization function. So even if you did keep track of sr, there's no way it can be passed to your initialization function.
You can do what you want using the impure parts of OCaml. E.g., you could save sr in a global reference variable at each step and retrieve it in the next call to the initialization function. However, this is really quite a cumbersome way to produce your list.
I would suggest not using List.init. You can write a straightforward recursive function to do what you want. (If you care about tail recursion, you can write a slightly less straightforward function.)
using a recursive function will increase the complexity so i think that initializing directly the list (or array) at the corresponding length will be better but i don't really know how to get a different value at each _i like Jeffrey Scofield said i am not really familiar with ocaml especially sequences so i have some difficulties doing that:(
I'm coding in haskell and want to know how find a certain element in mutiple list.
Here an example let say:
x = [(1,2,3,4,5),
(3,4,5,6,6),
(5,6,2,1,1),
(1,2,5,6,2)];
Let say I want to find the 3rd element of each list.
So the program will print out 4,6,1,6
I know about the !! but when I do something like x !! 3, it prints out the third row(1,2,5,6,2).
I want it so it print out the 3rd element of each list.
What you've provided is not actually a list of lists, but a list of tuples. Tuples have a special type based on the number and type of their elements, so the type of your x above is [(Int,Int,Int,Int,Int)].
Unlike lists, which allow us to extract values by index with the !! operator (ex. [1,2,3] !! 1 = 2), in order to extract specific values from a tuple we must pattern match the entire tuple, giving some name to the value we wish to extract and using it in our return value. To extract the fourth value from a tuple of holding 5 values, we could write a function like this:
f (a,b,c,d,e) = d
Or, as an anonymous function (because, if we are only going to use it when mapping over the list, it's nice to not bother assigning it a name):
(\(a,b,c,d,e) -> d)
Since we only care about the fourth value, we can choose to discard all others (you said third but meant index 3 -> 4th term above?):
(\(_,_,_,x,_) -> x)
Now we have a list of such tuples, and we'll want to apply it to each. We can do this with map, which will apply the function to each and return a list of the third value from each tuple:
f xs = map (\(_,_,_,x,_) -> x) xs
Or, with eta-reduction:
f = map (\(_,_,_,x,_) -> x)
Example usage:
gchi>> f [(1,2,3,4,5),(3,4,5,6,6),(5,6,2,1,1),(1,2,5,6,2)]
[4,6,1,6]
I am reading the book by jason and do not quite understand the following program:
let fact2 i =
let rec loop accum i =
if i = 0 then
accum
else
loop (i * accum) (i - 1)
in
loop 1
How is accum initialized?
What is the meaning of the last two lines (i.e. in loop 1)? loop has two parameters. why only one is passed here (i.e. loop 1).
Thank you very much!!!
I think that it's a mistake in implementation. Last line should be
loop 1 i
Integer 1 initialises accum from loop function and i initializes i in the same function.
Note that the lines starting with let rec loop accum i define a function. So accum is initialized when the function is called. This happens in the last line. As Kakadu points out, there's a transcription error in your post. The last line should say loop 1 i which (in essence) initializes accum to 1.
I think you have an extra "i" in the first line. That makes fact2 take an extra argument which is never used. Instead it should read:
let fact2 =
The last line that says "loop 1" is often called a partial application.
Ocaml usually uses curried functions, so another way of thinking of it is that loop actually takes one parameter and returns a function which in turn takes another parameter and returns an int.
In this particualar case, the type of (loop 1) is int -> int meaning it takes an int and returns an int. The type of loop is int -> int -> int meaning it takes an int and return an int -> int. It can also be written more explicitly as int -> (int -> int) since -> is right-associative.
To answer the other question, accum is initialized by passing 1 to loop.
Here is more information on currying: http://en.wikipedia.org/wiki/Currying
And of course, adding another "i" as others are suggesting would also work, but then you'd still be confused when others left it out.
It may help to think of let f x y = ... as being equivalent to let f = fun x -> fun y -> ...
And of course let f x = g x is the same as let f = g except the former will only work when g is a function.
I need a function that recursively returns (not prints) all values in a list with each iteration. However, every time I try programming this my function returns a list instead.
let rec elements list = match list with
| [] -> []
| h::t -> h; elements t;;
I need to use each element each time it is returned in another function that I wrote, so I need these elements one at a time, but I can't figure this part out. Any help would be appreciated.
Your function is equivalent to :
let rec elements list =
match list with
| [] -> []
| h :: t -> elements t
This happens because a ; b evaluates a (and discards the result) and then evaluates and returns b. Obviously, this is in turn equivalent to:
let elements (list : 'a list) = []
This is not a very useful function.
Before you try solving this, however, please understand that Objective Caml functions can only return one value. Returning more than one value is impossible.
There are ways to work around this limitation. One solution is to pack all the values you wish to return into a single value: a tuple or a list, usually. So, if you need to return an arbitrary number of elements, you would pack them together into a list and have the calling code process that list:
let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *)
List.iter print_int (my_function ()) (* Print four values *)
Another less frequent solution is to provide a function and call it on every result:
let my_function action =
action 1 ;
action 2 ;
action 3 ;
action 4
in
my_function print_int
This is less flexible, but arguably faster, than returning a list : lists can be filtered, sorted, stored...
Your question is kind of confusing - you want a function that returns all the values in a list. Well the easiest way of returning a variable number of values is using a list! Are you perhaps trying to emulate Python generators? OCaml doesn't have anything similar to yield, but instead usually accomplishes the same by "passing" a function to the value (using iter, fold or map).
What you have currently written is equivalent to this in Python:
def elements(list):
if(len(list) == 0):
return []
else:
list[0]
return elements(list[1:])
If you are trying to do this:
def elements(list):
if(len(list) > 0):
yield list[0]
# this part is pretty silly but elements returns a generator
for e in elements(list[1:]):
yield e
for x in elements([1,2,3,4,5]):
dosomething(x)
The equivalent in OCaml would be like this:
List.iter dosomething [1;2;3;4;5]
If you are trying to determine if list a is a subset of list b (as I've gathered from your comments), then you can take advantage of List.mem and List.for_all:
List.for_all (fun x -> List.mem x b) a
fun x -> List.mem x b defines a function that returns true if the value x is equal to any element in (is a member of) b. List.for_all takes a function that returns a bool (in our case, the membership function we just defined) and a list. It applies that function to each element in the list. If that function returns true for every value in the list, then for_all returns true.
So what we have done is: for all elements in a, check if they are a member of b. If you are interested in how to write these functions yourself, then I suggest reading the source of list.ml, which (assuming *nix) is probably located in /usr/local/lib/ocaml or /usr/lib/ocaml.