I am trying to create a generic sequence, that would behave the following:
val generic_sequence= fn : (int -> int) -> int seq
that is, It should receive as an input a function:
foo: int -> int
and create a sequence that activates foo on all natural numbers.
I wrote the following auxiliary code (works fine):
datatype 'a seq = Nil
| Cons of 'a * (unit-> 'a seq);
fun head (Cons(x,_)) = x;
fun tail (Cons (_,xf)) = xf();
fun naturals k = Cons(k,fn()=>naturals (k+1));
and when I tried implementing the generic sequence I got stuck.
This is where I've got.
fun aux (Cons(x,xf))= (Cons(foo x,(fn=>aux((xf())))));
fun generic_seq foo = (aux (from 0));
I have 2 problems:
It doesn't compile
I am not sure if my approach is correct
Would appreciate some help here.
Ok, I figured it out,
I created a mapq function and it basically did everything for me.
fun mapq f Nil = Nil
| mapq f (Cons (x,xf)) = Cons (f(x), fn() => mapq f (xf()));
Related
I've been doing a lot of practice recently in sml and one problem I've found in my textbook was asking to create a function that applies a function to the odd indexed values in a list. When trying to solve this I don't really understand how to get every other value. for instance
fun something f [] = 0
| something f (x:xs) =
Here above I know that we can get the values in order via the x value but is there a way to now apply this to get only odd indexed values? Sorry if this is a simple question sml has been an interesting but confusing language.
You can "destructure" the list with pattern matching in that case too – patterns can be arbitrarily complex.
For instance, a::b::bs matches a list with at least two elements, a::b::c::bs at least three, and so on.
If we index the first element 1:
fun everyOther _ [] = []
| everyOther f [x] = [f x]
| everyOther f (x::y::xs) = (f x)::y::(everyOther f xs)
Test:
val everyOther = fn : ('a -> 'a) -> 'a list -> 'a list
val it = () : unit
- fun square x = x * x;
val square = fn : int -> int
- everyOther square [1,2,3,4];
val it = [1,2,9,4] : int list
- everyOther square [1,2,3,4,5];
val it = [1,2,9,4,25] : int list
The case of the first element being indexed 0 rather than 1 left as an exercise.
Say we have such a lazy list:
type 'a lazy_list_t = Cons of 'a * (unit -> 'a lazy_list_t)
Does it make sense to have a function like the iter in regular list:
val iter : ('a -> unit) -> 'a list -> unit
List.iter f [a1; ...; an] applies function f in turn to a1; ...; an. It is equivalent to begin f a1; f a2; ...; f an; () end.
Or is it possible to produce iter_lazy like
val iter_lazy: ('a -> unit) -> 'a lazy_list -> unit
No, it does not make much sense.
First, and you probably noticed it, all your list are infinite (you do not have an empty element). So, only examples of inhabitant of your type are somehow using a recursive function, eg. :
let omega =
let rec f n = Cons (n, fun () -> f (n + 1)) in
f 0
This implements the infinite stream [ 0, 1, 2, 3, ...
If you WANT a diverging program you could implement :
let rec iter f (Cons (n, g)) = f n; iter f (g ())
but if you do iter print_int omega it will result output all integers which will take some time.
So itering is not an option. What would work is "mapping", you can implement the function :
val map: ('a -> 'b) -> 'a lazy_list_t -> 'b lazy_list
let rec map f (Cons (x, g)) = Cons (f x, fun () -> map f (g ()))
Notice how the recursive call to map is "protected" by the "fun () ->" so it will not trigger "right away" but only each time the tail of your lazy list is forced.
You can use this to lazily compute on infinite streams, eg :
let evens = map ((*) 2) omega
computes the stream [0; 2; 4; 6; 8; ...
Note, that you could use it to implement some sort of "iter" by mapping a function that does a side_effect eg.
let units = map print_int evens
will output right away the number "0" and outputs the stream [(); (); (); ... and each time you force one of the "tail" of this stream it will output the corresponding number (it can happen multiple times). Example:
(* Force the tail *)
val tl : 'a lazy_list_t -> 'a lazy_list_t
let tl (Cons (_, g)) = g ()
let () = begin
tl units; (* ouputs "2" *)
tl (tl units); (* outputs "24" *)
tl units; (* outputs "2" *)
end
(I haven't tried the code so there may be some typos).
I'm trying to "double" filter through two lists depending on passing a datatype test painfully without recursion using HOPs. Below is my very-ugly attempt at a solution...
datatype 'a test = Test of ('a -> bool) * string;
fun foo xs lst =
let
fun foo_bar(x, ls) =
let
val tests = (List.filter (fn (Test(f, str)) => (f x)) ls)
in
(List.map (fn (Test(f, str)) => str) tests)
end
in
(List.map (fn x => foo_bar(x, lst)) xs)
end;
allPass: 'a list -> 'a test list -> 'a test list;
allPass [1, 2, 40, 150] [positive, even] should return the string "pos".
Currently, my function is returning a nested list: [["pos"], ["pos even"], ["pos even"], ["pos even"]]. Is there a non-recursive way to extract just "pos" from this result or am I going about solving this problem in entirely the wrong direction?
You're going in the right direction, but you're not quite there yet. Here's what I think you want.
Take a list of value and a list of Tests. Return a list of the names of the tests for which all of the values pass.
Okay, so we need to:
Filter the list of tests. The predicate for a test is that all the values must pass.
Extract the names of the tests that passed.
Okay, so how do we figure out if all the values in a list pass one test? Simple, we use List.all.
List.all : ('a -> bool) -> 'a list -> bool
We can define a function:
fun allPassesTest xs (Test(f,s)) = List.all f xs
This will return true if and only if all of the values in xs pass the test. Now we filter the list of tests, based on this function:
fun allPass xs tests = List.filter allPassesTest xs tests
However, this returns a 'a test list instead of a string list, so you'll need to extract the names.
fun name (Test(f,s)) = s
fun allPass xs tests = map name (List.filter allPassesTest xs tests)
The question
1 Streams and lazy evaluation (40 points)
We know that comparison sorting requires at least O(n log n) comparisons where were are sorting n elements. Let’s say we only need the first f(n) elements from the sorted list, for some function f. If we know f(n) is asymptotically less than log n then it would be wasteful to sort the entire list. We can implement a lazy sort that returns a stream representing the sorted list. Each time the stream is accessed to get the head of the sorted list, the smallest element is found in the list. This takes linear time. Removing the f(n) elements from the list will then take O(nf(n)). For this question we use the following datatype definitions. There are also some helper functions defined.
(* Suspended computation *)
datatype 'a stream' = Susp of unit -> 'a stream
(* Lazy stream construction *)
and 'a stream = Empty | Cons of 'a * 'a stream'
Note that these streams are not necessarily infinite, but they can be.
Q1.1 (20 points) Implement the function lazysort: int list -> int stream'.
It takes a list of integers and returns a int stream' representing the sorted list. This should be done in constant time. Each time the stream' is forced, it gives either Empty or a Cons(v, s'). In the case of the cons, v is the smallest element from the sorted list and s' is a stream' representing the remaining sorted list. The force should take linear time. For example:
- val s = lazysort( [9, 8, 7, 6, 5, 4] );
val s = Susp fn : int stream'
- val Cons(n1, s1) = force(s);
val n1 = 4 : int
val s1 = Susp fn : int stream'
- val Cons(n2, s2) = force(s1);
val n2 = 5 : int
val s2 = Susp fn : int stream'
- val Cons(n3, s3) = force(s2);
val n3 = 6 : int
val s3 = Susp fn : int stream'
Relevant definitions
Here is what is given as code:
(* Suspended computation *)
datatype 'a stream' = Susp of unit -> 'a stream
(* Lazy stream construction *)
and 'a stream = Empty | Cons of 'a * 'a stream'
(* Lazy stream construction and exposure *)
fun delay (d) = Susp (d)
fun force (Susp (d)) = d ()
(* Eager stream construction *)
val empty = Susp (fn () => Empty)
fun cons (x, s) = Susp (fn () => Cons (x, s))
(*
Inspect a stream up to n elements
take : int -> 'a stream' -> 'a list
take': int -> 'a stream -> 'a list
*)
fun take 0 s = []
| take n (s) = take' n (force s)
and take' 0 s = []
| take' n (Cons (x, xs)) = x::(take (n-1) xs)
My attempt at a solution
I tried to do the following which get the int list and transforms it to int stream':
(* lazysort: int list -> int stream' *)
fun lazysort ([]:int list) = empty
| lazysort (h::t) = cons (h, lazysort(t));
But when calling force it does not return the minimum element. I have to search for the minimum, but I do not know how... I thought of doing insertion sort like following:
fun insertsort [] = []
| insertsort (x::xs) =
let fun insert (x:real, []) = [x]
| insert (x:real, y::ys) =
if x<=y then x::y::ys
else y::insert(x, ys)
in insert(x, insertsort xs)
end;
But I have to search for the minimum and to not sort the list and then put it as a stream...
Any help would be appreciated.
Each time the stream is accessed to get the head of the sorted list, the smallest element is found in the list.
You are on the correct path with the placement function (sort of... I don't know why you have real types instead of int when there will only be int streams . Your pattern would not match if you have not realized by now).
fun insertsort ([]:int list) = empty
| insertsort (h::t) =
let
fun insert (x:real, []) = [x] (* 1 *)
| insert (x:real, y::ys) = (* 2 *)
if x<=y then x::y::ys (* 3 *)
else y::insert(x, ys) (* 4 *)
in insert(x, insertsort xs) (* 5 *)
This is your helping inner magic for getting the smallest item each time.
Some hints/tips to make the above work
You should have only one argument
I don't think it matters to have less than or equal to (just less than should work .... have not really thought about that). Also you have to reach the bottom of the list first to tell which is the smallest so this is tail first. so that (* 1 *) is the first then each inside call of (* 2 *) till the outermost one.
That should be cons(x, insertsort xs) in (* 5 *) since you are returning a int stream' with the function.
I'm in your class and I think you're going about this the totally wrong way. I've solved the question, but I think it's a bit unethical for me to fully share the code with you. That said, here's a pointer:
you don't need to transform the int list into an int stream'. Firstly, this violates the rule that the initial call to lazysort must be done in constant time. Note that transforming it to an int stream' is done in linear time. What you need to do is provide an embedded sort function within the closure of the suspended stream you're returning (using a let block.) The first element of the stream would be the result of the sort function (done with the suspended closure.) The second element of the stream (which is just an int stream') should be a call to your lazysort function, because it returns an int stream'. Notice how this lets you avoid having to transform it. The sort function itself is quite simple, because you only need to find the smallest element and return the rest of the list without the element you found to be the smallest.
I'm currently trying to extend a friend's OCaml program. It's a huge collection of functions needed for some data analysis.. Since I'm not really an OCaml crack I'm currently stuck on a (for me) strange List implementation:
type 'a cell = Nil
| Cons of ('a * 'a llist)
and 'a llist = (unit -> 'a cell);;
I've figured out that this implements some sort of "lazy" list, but I have absolutely no idea how it really works. I need to implement an Append and a Map Function based on the above type. Has anybody got an idea how to do that?
Any help would really be appreciated!
let rec append l1 l2 =
match l1 () with
Nil -> l2 |
(Cons (a, l)) -> fun () -> (Cons (a, append l l2));;
let rec map f l =
fun () ->
match l () with
Nil -> Nil |
(Cons (a, r)) -> fun () -> (Cons (f a, map f r));;
The basic idea of this implementation of lazy lists is that each computation is encapsulated in a function (the technical term is a closure) via fun () -> x.
The expression x is then only evaluated when the function is applied to () (the unit value, which contains no information).
It might help to note that function closures are essentially equivalent to lazy values:
lazy n : 'a Lazy.t <=> (fun () -> n) : unit -> 'a
force x : 'a <=> x () : 'a
So the type 'a llist is equivalent to
type 'a llist = 'a cell Lazy.t
i.e., a lazy cell value.
A map implementation might make more sense in terms of the above definition
let rec map f lst =
match force lst with
| Nil -> lazy Nil
| Cons (hd,tl) -> lazy (Cons (f hd, map f tl))
Translating that back into closures:
let rec map f lst =
match lst () with
| Nil -> (fun () -> Nil)
| Cons (hd,tl) -> (fun () -> Cons (f hd, map f tl))
Similarly with append
let rec append a b =
match force a with
| Nil -> b
| Cons (hd,tl) -> lazy (Cons (hd, append tl b))
becomes
let rec append a b =
match a () with
| Nil -> b
| Cons (hd,tl) -> (fun () -> Cons (hd, append tl b))
I generally prefer to use the lazy syntax, since it makes it more clear what's going on.
Note, also, that a lazy suspension and a closure are not exactly equivalent. For example,
let x = lazy (print_endline "foo") in
force x;
force x
prints
foo
whereas
let x = fun () -> print_endline "foo" in
x ();
x ()
prints
foo
foo
The difference is that force computes the value of the expression exactly once.
Yes, the lists can be infinite. The code given in the other answers will append to the end of an infinite list, but there's no program you can write than can observe what is appended following an infinite list.