Standard SML datatype list - list

Datatype events = enter of string * real | exit of string *real;
So i have this Datatype and i have to write a function that takes a list of events as input and return that list sorted by the real part of events.
I tried to write some functions but didnt come up with anything good, any ideas?
this is the code i tried:
val rec ordina = fn
[] => []
|v1::v2::l => if (#2(v2)) > (#2(v1))
then ordina (v1::l)
else oridna (v2::1);
Errors i got:
poly: error: Can't find a fixed record type. Found near #2
poly: error: Can't find a fixed record type. Found near #2

Some feedback,
The datatype declaration should probably be
datatype event = Enter of string * real
| Exit of string * real
A single value contains a single event.
The plural is achieved by having a value of e.g. type event list.
Value constructors are usually written with an uppercase start letter.
In SML/NJ you have a generic sort function called ListMergeSort.sort. It takes a function with the type 'a * 'a -> bool where 'a = event in this case. You could then write a function,
fun cmp_event (event_a, event_b) = ...
that returns whether event_a should be ordered before event_b based on their real parts. Hint: First, make a helper function that extracts the real part. (Come up with a better name that reflects the purpose of the real part.)
fun get_real_part (Enter (_, r)) = ...
| get_real_part ... = ...
If you're not allowed to use ListMergeSort.sort, then make your own sort.

Related

Clarification needed in second parameter to List.init (F#)

Could you explain the second parameter in List.init
let test2 = List.init 100000 (fun _ -> System.Random().Next(-50, 51));;
From the declaration of List.init available here; what I understand is that init takes an int and "a function that takes an index and returns a generic value" as parameters. The return value is a list of the generic type passed.
But I don't understand how is the function being applied in the given let binding.
Thanks.
List.init takes an integer for the size of the list and then a function that will be used to fill each element. This function takes in the current index of the element being filled (ie. an int). The Type of the elements in your list then depends on the return type of the 2nd function. In your case an int.
In the example in the question the function fun _ -> System.Random().Next(-50, 51) will just pick random value to fill the list with. Since it is new-ing up Random every time you will get the same value every time because computers and randomness are not very well acquainted. the _ is used in many languages to indicate that we don't care about the value of the parameter because we are not going to use it. So here _ is used as an anonymous generic parameter.
For an actual "random" value you could move the Random() call outside the function and close over it or you could technically use the item index as a seed number. I am not recommending this but it does illustrate what that function takes.
let test1 = List.init 100000 (fun i -> System.Random(i).Next(-50, 51))
As I mentioned something like this is more likely what you are after:
//Random
let random = System.Random()
// int -> int
let generate (_:int) = random.Next(-50, 51)//note this has the signature we need for the 2nd parameter of List.init
// generate the list
let test2 = List.init 10 generate;;
The _ can also be used in matching. Here we have a tuple we want to deconstruct to get to it's values.
let person = ("Bob","Builder")
let (firstname,lastname) = person
let (_,surname) = person
If we don't care about the firstname we don't have to get it but can still use the same syntax, we just use _ to indicate we do not care about the value.
Reference Symbol and Operator reference
I think I understand now. fun _ -> System.Random().Next(-50, 51) is an anonymous function that uses _ as a wildcard placeholder for parameter and returns a random number.
So, it can be used as second parameter to init, and get a list of randomly generated integers back.

OCaml Signature with multiple types

I would like to represent some scalar value (e.g. integers or strings)
by either it's real value or by some NA value and later store them
in a collection (e.g. a list). The purpose is to handle missing values.
To do this, I have implemented a signature
module type Scalar = sig
type t
type v = Value of t | NA
end
Now I have some polymorphic Vector type in mind that contains Scalars. Basically, some of the following
module Make_vector(S: Scalar) = struct
type t = S.v list
... rest of the functor ...
end
However, I cannot get this to work. I would like to do something like
module Int_vector = Make_vector(
struct
type t = int
end
)
module Str_vector = Make_vector(
struct
type t = string
end
)
... and so on for some types.
I have not yet worked a lot with OCaml so maybe this is not the right way. Any advises on how to realize such a polymorphic Scalar with a sum type?
The compiler always responds with the following message:
The parameter cannot be eliminated in the result type.
Please bind the argument to a module identifier.
Before, I have tried to implement Scalar as a sum type but ran into
complexity issues when realizing some features due to huge match clauses. Another (imo not so nice) option would be to use option. Is this a better strategy?
As far as I can see, you are structuring v as an input type to your functor, but you really want it to be an output type. Then when you apply the functor, you supply only the type t but not v. My suggestion is to move the definition of v into your implementation of Make_vector.
What are you trying to do exactly with modules / functors? Why simple 'a option list is not good enough? You can have functions operating on it, e.g.
let rec count_missing ?acc:(acc=0) = function
| None::tail -> count_missing ~acc:(acc+1) tail
| _::tail -> count_missing ~acc tail
| [] -> acc ;;
val count_missing : ?acc:int -> 'a option list -> int = <fun>
count_missing [None; Some 1; None; Some 2] ;;
- : int = 2
count_missing [Some "foo"; None; Some "bar"] ;;
- : int = 1

function without args and return type in OCaml

First of all I usually programming in imperative languaes, that makes me hard to explain certain things. First of all is functions without args, and return types. Example is function that flattens a list:
# let rec flat = function
[] -> []
| h :: t -> h # flat t;;
val flat : 'a list list -> 'a list = <fun>
How OCaml interpreter know that:
My function flat need exactly one argument which is "list of lists".
Flat returns type is a list. Do the interpreter checks it with [] -> [] line?
let rec flat = function
[] -> []
| h :: t -> h # flat t;;
You used function keyword. function is a shortcut for match ... with. So the function you wrote is exactly like
let rec flat l =
match l with
[] -> []
| h :: t -> h # flat t
That's why ocaml knows your function has one parameter
Your function is recursive. [] -> [] is the basic case and it is also where the function will be stopped. And yes, interpreter checks it with [] -> [].
Furthermore, a function must have at least a unit parameter which is () or a normal parameter. If a function does not have anything, it is not a function, instead, it is a variable with a fixed value.
Let's have an example:
let f1 = Random.int 10;
f1 does not have any parameter, even without a () (here () is just like a method in Java without any parameter). Then f1 is a constant value which was generated by the Random. No matter when you call it, f1 will always be fixed.
let f2 () = Random.int 10;
f2 is a function. And each time you call f2(), the Random inside will generate a random in and returns it.
let rec flat = function
[] -> []
| h :: t -> h # flat t;;
Let's go through this a step at a time. The function keyword, as you might expect, gives a function. The basic syntax is function | pat1 -> branch1 | pat2 -> branch2, and what you get is a function of one argument that tries to match that argument against each pattern in turn, and for the first pattern that matches the result is the corresponding branch.
So that's how we know flat is a function. Moreover, we can see that its one argument is matched against [], which is a list. So flat must be a function that takes a list. We see that if the input is [] then the output is [], so it's a function that takes a list and returns a list.
Now let's look at that second pattern. h :: t is a pattern that matches a list and creates two new variable bindings: h is the first element of the list and t is all the rest of the elements. In particular, h has whatever type the elements of the input list have.
If you look at what happens if this pattern match succeeds, h # flat t, we see the list concatenation operator # applied to h and flat t. This means that h must be a list, and must be the same kind of list as flat t. So the elements of the input list are lists, and so is the output of the function.
This gives you flat : 'a list list -> 'a list.
To answer your questions directly, flat needs exactly one argument because it is defined with the function keyword and the return values of the branches are values and not functions (if the function branches were also functions, that would meant flat could have two or more arguments). It is a list because the pattern match is against list constructors, and it is a list of lists because h is an element of the list and is used with the # operator, which requires its arguments to be lists, so the elements of the list are lists.
There are actually three reasons why the return type must be a list:
In the first branch, a list [] is returned.
In the second branch, the result of # is returned, and # returns lists
Also in the second branch, flat t is called recursively, and then given as an argument to #. Since it is an argument to #, it must be a list, and so flat must return a list.
The third bullet point is especially interesting, because it shows you that it's not just how you create values that determines their type, but how you use them as well.

Generating an infinite list of Fibonacci sequence in ML

I have to generate an infinite list containing a Fibonacci sequence. I am new to ML so I want to check if this is correct.
-datatype 'a infist=NIL
= | CONS of 'a * (unit -> 'a inflist);
- fun fib a b = CONS (a , fn()=> fib b (a+b));
val fib=fn: int->int-int inflist
Is this what is called a generator function?
Will it give me an actual output i.e the infinite fib sequence when I give a and b inputs?
Your datatype definition and your function definition seem correct. Although I still would have preferred a Fibonacci function that does not expect any arguments, to avoid the possibility of getting wrong input:
fun fibonacci () =
let
fun fib(a,b) = Cons(a+b, fn() => fib(b,a+b))
in
Cons(0, fn()=> fib(0,1))
end
This is what I would call a stream
When you invoke it, it'll give an element of type infislist. You may consider writing some other functions to process your stream and interpret its contents. You may want see some examples of this in my another answer, for example, functions like takeWhile, take, filter, zip and toList.

Recursive function that returns all values in list (In OCaml)

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.