Suppose I have a map function like below:
let rec map f xs = match xs with
[] -> []
| hd :: tl -> f hd :: (map f tl)
I got some errors when I change the signature of map to let rec map xs f,
Could anyone pinpoint which knowledge I am lacking and explains why?
There's no problem if you change the definition and the recursive call.
# let rec map xs f = match xs with
[] -> []
| hd :: tl -> f hd :: (map tl f);;
val map : 'a list -> ('a -> 'b) -> 'b list = <fun>
# map [3; 5; 7] ((+) 1);;
- : int list = [4; 6; 8]
You should be able to switch the xs with the f
the only thing you have to make sure to change is the the order on line 3 where you have (map f tl) to (map tl f)
Related
I am trying to write methods on arbitrary trees in OCaml. Here is my tree constructor:
type 'a tree =
| Leaf of 'a
| Node of ('a tree) list
I am having trouble with fold_tree:
let rec fold_tree (f : 'b list -> 'b) (g : 'a -> 'b) (t : 'a tree): 'b.
For example, fold_tree sum (fun x -> x) (node [node [leaf 7; leaf 8]; leaf 9])=24
Not sure what you are trying to accomplish here... Is it something like this?
let rec fold_tree f acc (t:'a tree) =
match t with
| Leaf e -> f acc e
| Node l ->
List.fold_left
(
fun a e -> fold_tree f a e
) acc l
Example of usage:
let data = Node [Node [Leaf 7; Leaf 8; Leaf 100]; Leaf 9; Leaf 10;]
let ans = fold_tree (fun a e -> a + e) 0 data
let () = print_endline(string_of_int ans)
I set myself the following challenge (and failed):
I want to write a map functional, map f lofls, that takes a function, f 'a -> 'b and a list of lists, lofls 'a list list and applies the function f on every element of the list of lists. The constraint that I added is that I am not allowed to used nested maps for lists, and I have to do it recursively.
I tried to do it in F# but any language should do. Any ideas?
Edit
Here is my attempt (which works but is ugly and I am not a fan of the use of rev either . . .)
let map f lis =
let rec map2 f lis aux =
match (lis, aux) with
|([], []) -> []
|([], aux) -> [aux]
|(hd::tl, aux) ->
match hd with
|[] -> (List.rev aux) :: (map2 f tl [])
|x::xs -> map2 f (xs::tl) ( (f x) :: aux )
map2 f lis []
(I also realised that this has been posted in a more concise form already)
Lets go step by step, from simple to complex.
This is the signature that you want your map function to have:
('a -> 'b) -> 'a list list -> 'b list list
The simple solution is this:
let map0 (f:'a -> 'b) (lofls:'a list list) : 'b list list = lofls |> List.map (List.map f)
But that one is not recursive and it uses nested maps.
A recursive solution could be this:
let rec map1 (f:'a -> 'b) (lofls:'a list list) : 'b list list =
match lofls with
| [] -> []
| l::rest -> (List.map f l) :: map1 f rest
It is recursive although it is still calling List.map in there.
So, here is the next level:
let rec map (f:'a -> 'b) (lofls:'a list list) : 'b list list =
match lofls with
| [ ] -> [ ]
| [ ] :: rest -> [ ] :: (rest |> map f)
| ( e::restl ) :: rest ->
match restl :: rest |> map f with
| [ ] -> [ ]
| [ ] :: rest -> [ f e ] :: rest
| ( restl ) :: rest -> ( f e :: restl ) :: rest
Another way:
let rec mapNested f lofls =
match lofls with
| [] -> []
| h::t -> (map f h) :: (mapNested f t)
and map f lst =
match lst with
| [] -> []
| h::t -> (f h) :: (map f t)
If this were a homework question, which I am sure it is not, the answer depends on what constitutes "a nested map for lists".
A construct like map [] (map [] f) can be rewritten with pipelining as f |> map [] |> map [], or with the function composition operator as (map [] >> map []) f, but may be still considered a nested map.
let mapNested f =
let rec map acc g = function
| [] -> List.rev acc
| x::xs -> map (g x::acc) g xs
f |> map [] |> map []
// val mapNested : f:('a -> 'b) -> ('a list list -> 'b list list)
This is the opportunity to demonstrate your grasp of lambda calculus and the Y combinator. Nested passing of the map function as an argument should clearly pass muster.
let rec Y f x = f (Y f) x
let map f acc g = function
| [] -> List.rev acc
| x::xs -> f (g x::acc) g xs
let map1 f =
Y map [] f
// val map1 : f:('a -> 'b) -> ('a list -> 'b list)
let map2 f =
Y map [] f
|> Y map []
// val map2 : f:('a -> 'b) -> ('a list list -> 'b list list)
A tail recursive way
let mapNested f lofls =
let rec map f lst acc =
match lst with
| [] -> List.rev acc
| h::t -> map f t (f h :: acc)
map (fun x -> map f x []) lofls []
I'm not sure why this question is tagged with SML, but since it is, here is how it can be done in SML:
First, this is the idiomatic solution that you're explicitly avoiding:
fun mapmap f = map (map f)
(You could write val mapmap = map o map if it weren't for ML's value restriction.)
And if you'd like to write mapmap using explicit recursion:
fun mapmap f [] = []
| mapmap f (xs::xss) = map f xs :: mapmap f xss
and map f [] = []
| map f (x::xs) = f x :: map f xs
One reason behind why this function is hard to write with a single explicitly recursive function is that the call stack is used for two things:
Collecting the result of each inner list, and
Collecting the result of the outer list.
One of those uses of the call stack can be turned into an explicit stack in an accumulating argument. This is how e.g. a tail-recursive rev is defined:
fun rev xs =
let fun aux [] acc = acc
| aux (x::xs) acc = aux xs (x::acc)
in aux xs [] end
The accumulating argument similarly isn't needed in the interface to mapmap, so it can be hidden in an inner helper function. So a single function that performs explicit recursion on both the inner and the outer list is complicated by this explicit bookkeeping:
fun mapmap f xss =
let fun aux f [] _ = []
| aux f ([]::xss) ys = rev ys :: aux f xss []
| aux f ((x::xs)::xss) ys = aux f (xs::xss) (f x :: ys)
in aux f xss [] end
I have this quite simple function which takes an int and adds it to the head of the list and is recursively called with i multiplied with itself:
let rec f i = function
| [] -> []
| x::xs -> (x+i)::f (i*i) xs
f 2 [1;2;3]
val it : int list = [3; 6; 19]
Now, I'm attempting to rewrite it using a continuation, but I'm a little stuck. Here's what I've come up with so far:
let fC i l =
let rec loop cont = function
| [] -> []
| x::xs -> cont(x+i)::loop (fun acc -> (acc*acc)) xs
loop id l
fC 2 [1;2;3] //Expected [3;6;19]
val it : int list = [3; 16; 25]
Any hints to what I'm doing wrong?
Looking at this questions and the comments it seems to me that there is some confusion.
Tail recursive does not necessary mean continuation passing style (CPS).
Here's the function in CPS:
let f' i p =
let rec loop i p k =
match p with
| [] -> k []
| x::xs -> loop (i*i) xs (fun a -> k ((x+i)::a))
loop i p id
And of course, it's tail recursive. But you can also write it tail recursive by using an accumulator instead of a continuation:
let f'' i p =
let rec loop i p acc =
match p with
| [] -> acc
| x::xs -> loop (i*i) xs ((x+i)::acc)
loop i p [] |> List.rev
See also the answer to this question to understand better CPS.
I am trying to get first and last element of the list in OCaml. I expect that my function will be like
'a list -> 'a * 'a
What I am trying to do is
let lista = [1;2;3;4;6;0];;
let rec first_last myList =
match myList with
[x] -> (List.hd lista,x)
| head::tail ->
first_last tail;;
first_last lista;;
Of course because of I made list as integer then I am doing this syntax like
*int list -> int * 'a
The point is that I dont have idea how to do this function for 'a.
Whats the direction?
The direction is to write two different functions first and last and implement the first_and_last function as:
let first_and_last xs = first xs, last xs
Another possibility with only one function:
let rec first_last = function
| [] -> failwith "too bad"
| [e] -> failwith "too bad"
| [e1;e2] -> (e1,e2)
| e1 :: _ :: r -> first_last (e1::r)
You may prefer it like that:
let rec first_last myList = match myList with
| [] -> failwith "too bad"
| [e] -> failwith "too bad"
| [e1;e2] -> (e1,e2)
| e1 :: _ :: r -> first_last (e1::r)
You can create two separate functions to return first element and last element, and then in your first_and_last function return a tuple (first_element, last_element).
let rec first_element list =
match list with
| [] -> failwith "List is empty"
| first_el::rest_of_list -> first_el
let rec last_element list =
match list with
| [] -> failwith "List is empty"
| [x] -> x
| first_el::rest_of_list -> last_element rest_of_list
You can create a helper function that has a base-case of the empty-list - for which it returns itself, and otherwise checks if the next recursive call will return an empty list. If it does, return the current element (which is by definition the last element in the list), and if it doesn't, return what was returned by the recursive call.
For the regular (non-helper) method, if the list is at least one element long (i.e. hd::tl = hd::[]) then you can just concatenate the list you got from the last function onto the head from ls.
It can be implemented as follow:
let rec last ls =
match ls with
| [] -> []
| hd::tl -> let next = last tl in
if next = [] then [hd]
else next
;;
let first_last ls =
match ls with
| [] -> failwith "Oh no!!!!! Empty list!"
| hd::tl -> hd::last tl
;;
Yet another take on this problem.
let first_last xs =
let rec last_non_empty = function
| [x] -> x
| _ :: xs' -> last_non_empty xs'
| [] -> failwith "first_last: impossible case!"
in
match xs with
| [] -> failwith "first_last"
| x::_ -> (x, last_non_empty xs)
Some properties of this implementation:
(1) it meets the specification 'a list -> 'a * 'a:
utop > #typeof "first_last";;
val first_last : 'a list -> 'a * 'a
(2) it works for singleton lists: first_last [x] = (x,x):
utop> first_last [1];;
- : int * int = (1, 1) utop> first_last ["str"];;
- : bytes * bytes = ("str", "str")
(3) it's tail-recursive (hence it won't cause stack overflow for sufficiently big lists):
utop > first_last (Array.to_list (Array.init 1000000 (fun x -> x+1)));;
- : int * int = (1, 1000000)
(4) it traverses the input list one time only; (5) it avoids creating new lists as it goes down the recursive ladder; (6) it avoids polluting the namespace (with the price of not allowing the reuse of a function like last).
And another rather simple variant, from the first principles (I was trying to illustrate "wishful thinking" in the spirit of the SICP book):
(* Not tail-recursive, might result in stack overflow *)
let rec first_last = function
| [] -> failwith "first_last"
| [x] -> (x,x)
| x :: xs -> (x, snd (first_last xs))
You could write it like this:
let first_last = function
| [] -> assert false
| x :: xs -> (x, List.fold_left (fun _ y -> y) x xs)
Or, if you are using the Base library, you could write in this way:
let first_last xs = (List.hd_exn xs, List.reduce_exn ~f:(fun _ y -> y) xs)
The basic idea is that List.fold_left (fun _ y -> y) x xs will compute the last element of x :: xs. You can prove this by induction on xs: if xs = [] then List.fold_left (fun _ y -> y) x [] = x, which is the last element of x :: []; moreover, if xs = x' :: xs' then List.fold_left (fun _ y -> y) x (x' :: xs') can be rewritten as List.fold_left (fun _ y -> y) x' xs', because List.fold_left f acc (x :: xs) = List.fold_left (f acc x) xs, hence we are finished, because this is the last element of x' :: xs' by our induction hypothesis.
I implemented a non-in-place version of selection sort in OCaml.
let sort compare_fun l =
let rec find_min l' min_l origin_l =
match l' with
| [] ->
if min_l = [] then (min_l, l')
else
let min = List.hd min_l
in
(min_l, List.filter (fun x -> if x != min then true else false) origin_l)
| x::tl ->
if min_l = [] then
find_min tl [x] origin_l
else
let c = compare_fun (List.hd min_l) x
in
if c = 1 then
find_min tl [x] origin_l
else if c = 0 then
find_min tl (min_l # [x]) origin_l
else
find_min tl min_l origin_l
in
let rec insert_min l' new_l =
match l' with
| [] -> new_l
| _ ->
let (min_l, rest) = find_min l' [] l'
in
insert_min rest (new_l # min_l)
in
insert_min l [];;
My idea is that in a list, every time I find the list of minimum items (in case of duplicate values) and add this min list to the result list, then redo the finding_min in the rest of the list.
I use List.filter to filter out the min_list, so the resulting list will be the list for next find_min.
I find my implementation is quite complicated, and far more complicated than the Java in-place version of selection sort.
Any suggestions to improve it?
Edit: Here's a much better implementation: http://rosettacode.org/wiki/Sorting_algorithms/Selection_sort#OCaml
here's my own crappier implementation
(* partial function - bad habit, don't do this. *)
let smallest (x::xs) = List.fold_right (fun e acc -> min e acc) xs x
let remove l y =
let rec loop acc = function
| [] -> raise Not_found
| x::xs -> if y = x then (List.rev acc) # xs else loop (x::acc) xs
in loop [] l
let selection_sort =
let rec loop acc = function
| [] -> List.rev acc
| xs ->
let small = smallest xs in
let rest = remove xs small in
loop (small::acc) rest
in loop []