I have recursive function, for course the branch of the tree
type tree = Node of bool ref * (char * tree) list ref
type cours= tree ->char list -> char list* char list * tree
let cours t word=
let rec cours_tree t word l1 l2=match t,word with
| Noeud(r,n),[] -> Noud (r,n), l1 , l2
| Noeud (r,n),x::h when (List.mem_assoc x !n) ->
x::l1,cours_tree (List.assoc x !n) h l1 l2
| Noeud (r,{content=(c,b)::n),x::h ->
x::l2,cours_tree (List.assoc x b) h l1 l2
in
cours_tree t word [] []
I would expect this to Browse a tree from a given list of characters, and return the subtree reached, the character list and the list of those who could not be reached;
But I'm getting an error:
Error: This expression has type char list * 'a
but an expression was expected of type 'a
The type variable 'a occurs inside char list * 'a#
I dont know where is my problem.
There are many problems:
Noud and Noeud are undefined constructors.
Unmatched { when you attempt to pattern match on the ref.
First match case returns tree * list * list but the other cases
return infinite types.
Incorrect ref pattern matching syntax. content should be contents.
Type error in the second List.assoc. b is a tree but an expression of type (char * 'a) list is expected.
The following code fixes the problems and while compile, but will not run correctly as the problem description you gave is not complete:
type tree = Node of bool ref * (char * tree) list ref
type cours = tree -> char list -> char list * char list * tree
let cours t word =
let rec cours_tree t word l1 l2 =
match t, word with
| Node (r, n), [] -> Node (r, n), l1, l2
| Node (r, n), x::h when List.mem_assoc x !n ->
let t', l1', l2' = cours_tree (List.assoc x !n) h l1 l2 in
t', x::l1', l2'
| Node (r, {contents = (c, b)::n}), x::h ->
let t', l1', l2' = cours_tree (List.assoc x n) h l1 l2 in
t', l1', x::l2'
in cours_tree t word [] []
Related
How can I make this function can fit with List and Int?
type 'a tree =
| Leaf
| Node of 'a tree * 'a * 'a tree;;
let rec fold_inorder f acc t =
match t with
| Leaf -> acc
| Node (l, x, r) ->
let ar = fold_inorder f acc r in
let an = x :: ar in
fold_inorder f an l;;
I am trying to
fold_inorder (fun acc x -> acc + x) 0 (Node (Node (Leaf,1,Leaf), 2, Node (Leaf,3,Leaf)));;
But give me error:
Error: This expression has type int but an expression was expected of type
'a list
You've restricted your accumulator type to being a list. In your recursion, you write
let an = x :: ar in
fold_inorder f an l;;
an is clearly a list (it was constructed using the :: list constructor), and it's being passed as the second argument to fold_inorder. Hence, fold_inorder can only accept lists as the second argument. On the other hand, when you call fold_inorder at the bottom, you pass 0 as the second argument, which is an integer and not a list, hence the error.
Rather than using :: to build an (the middle accumulator), you should use your supplied f function, which was given in order to combine values.
let an = f ar x in
Hello I'm trying to write a program in OCaml and was wondering if there is a way to get from list of pairs : [(1,2);(2,3);(3;5)] to a list where pairs are multiplied [2;6;15] this is what i have tried but it's giving me Exception: Failure "hd"
let rec mul l=
let x=(List.hd l) and y=(List.tl l) in
((fst x)*(snd x))::(mul y);;
mul [(3, 5); (3, 4); (3, 3);];;
What you want essentially is List.map (uncurry ( * )).
# let uncurry f (a, b) = f a b;;
val uncurry : ('a -> 'b -> 'c) -> 'a * 'b -> 'c = <fun>
# List.map (uncurry ( * )) [(3, 5); (3, 4); (3, 3);];;
- : int list = [15; 12; 9]
(uncurry is a basic FP function, but unfortunately it isn't defined in OCaml's fairly sparse standard library. But as you can see the definition is straightforward.)
To be honest, I think there must be simpler methods. Specifically, you have a list of n elements which are pairs (so a list of type (int * int) list) and you want to get a list of the same size, but which is the result of multiplying the two members of the pair. So, going from an (int * int) list to an int list.
As the objective is to preserve the size of the list, you can rephrase the statement by saying "I would like to apply a function on each element of my list". It is possible to do this manually, using, for example, pattern matching (which makes it possible to be explicit about the treatment of the empty list):
let rec mult my_list =
match my_list with
| [] -> (* case if my list is empty *)
[] (* The process is done! *)
| (a, b) :: tail -> (* if I have, at least, one element)
(a * b) :: (mult tail)
But generally, applying a function to each element of a list and preserving its size is called "mapping" (roughly), and fortunately there is a function in the standard OCaml library which allows this, and it is called, logically: List.map, here is its type: val map : ('a -> 'b) -> 'a list -> 'b list which could be translated as: give me a function which goes from 'a to 'b, a list of 'a and I can produce a list of 'b for you.
Here, we would like to be able to apply a function that goes from (int * int) -> int, for example: let prod (x, y) = x * y. So let's try to reimplement mult in terms of map:
let mult my_list =
let prod (x, y) = x * y in
List.map prod my_list
And voila, the pattern captured in the first purpose is exactly the idea behind List.map, for each element of a list, I apply a function and I keep the result of the function application.
Here is a working solution with the least amount of modification to your original code:
let rec mul l =
match l with
| [] -> [] (* <-- Deal with the base case *)
| _ -> (* Same as before --> *)
let x = (List.hd l) and y = (List.tl l) in
((fst x)*(snd x))::(mul y);;
Note that we just need to consider that happens when the list is empty, and we do that by matching on the list. The recursive case stays the same.
I don't have any idea on how to change the code for my add function.
type trie = Node of bool * (char * trie) list
let explode word =
let rec explode' i acc =
if i < 0 then acc else explode' (i-1) (word.[i] :: acc)
in explode' (String.length word - 1) []
let rec exists w tr = match w, tr with
| [], Node (b, _) -> b
| h::t, Node (_, l) -> try exists t (List.assoc h l) with Not_found -> false
let rec add w tr = match w, tr with
| [], Node (_, l) -> Node (true, l)
| h :: t, Node (b, l) -> try add t (List.assoc h l)
with Not_found -> Node (false, (h, add t tr) :: l)
The problem is when List.assoc h l finds something , then I don't keep track of my structure, no Node is built during the recursive call so I am losing data.
Example :
# let empty = Node(true, []);;
- : trie = Node (true, [])
# let w = explode "hi";;
val w : char list = ['h'; 'i']
# let ww = explode "hit";;
val ww : char list = ['h'; 'i'; 't']
# let tr = add w x;;
val tr : trie = Node (false, [('h', Node (false, [('i', Node (true, []))]))])
# add ww tr;;
- : trie = Node (false, [('t', Node (true, []))])
It seems your basic plan is to work down through the data structure with List.assoc, then add your new node when you find the right spot. This makes sense if you can modify the structure. However, your data structure is immutable. With immutable data, your basic plan must be to build a new data structure rather than to modify the old one. So you have to imagine yourself finding the right spot while keeping traack of the old structure along the way, then building up a new structure starting from the spot.
Here's some code that keeps an association list counting the number of instances of characters seen so far. Note that it returns a new association list rather than modifying the old one (which is impossible):
let rec add_char_count list char =
match list with
| [] -> [(char, 1)]
| (hchar, hcount) :: t ->
if hchar = char then (hchar, hcount + 1) :: t
else (hchar, hcount) :: add_char_count t char
The recursive call (hchar, hcount) :: add_char_count t char is the spot where the old structure is remembered. It rebuilds the old structure from the part of the list before where the new character is added.
I want to make function maptree with standard ML.
If function f(x) = x + 1;
then
maptree(f, NODE(NODE(LEAF 1,LEAF 2),LEAF 3));
should make result
NODE(NODE(LEAF 2,LEAF 3),LEAF 4))
I write the code like below.
datatype 'a tree = LEAF of 'a | NODE of 'a tree * 'a tree;
fun f(x) = x + 1;
fun maptree(f, NODE(X, Y)) = NODE(maptree(f, X), maptree(f, Y))
| maptree(f, LEAF(X)) = LEAF(f X);
but when I execute this code like this
maptree(f, (NODE(NODE(LEAF 1,LEAF 2),LEAF 3)));
result is not I want to
(NODE(NODE(LEAF 2,LEAF 3),LEAF 4)))
but
NODE(NODE(LEAF #,LEAF #),LEAF 4)).
Why this happened(not a number but #)?
# is used by the REPL when the data structure it prints is deeper than a pre-set value. If you increase that value, you'll get the result you excepted. I assume you're using SML/NJ, which calls that setting print.depth:
sml -Cprint.depth=20
- maptree(f, (NODE(NODE(LEAF 1,LEAF 2),LEAF 3)));
val it = NODE (NODE (LEAF 2,LEAF 3),LEAF 4) : int tree
You can find more options like these by executing sml -H. Look them up under the "compiler print settings" section:
compiler print settings:
print.depth (max print depth)
print.length (max print length)
print.string-depth (max string print depth)
print.intinf-depth (max IntInf.int print depth)
print.loop (print loop)
print.signatures (max signature expansion depth)
print.opens (print `open')
print.linewidth (line-width hint for pretty printer)
Some comments:
I would probably go with the definition
datatype 'a tree = Leaf | Node of 'a tree * 'a * 'a tree
so that trees with zero or two elements can also be expressed.
I would probably curry the tree map function
fun treemap f Leaf = Leaf
| treemap f (Node (l, x, r)) = Node (treemap f l, x, treemap f r)
since you can then partially apply it, e.g. like:
(* 'abstree t' returns t where all numbers are made positive *)
val abstree = treemap Int.abs
(* 'makeFullTree n' returns a full binary tree of size n *)
fun makeFullTree 0 = Leaf
| makeFullTree n =
let val subtree = makeFullTree (n-1)
in Node (subtree, n, subtree)
end
(* 'treetree t' makes an int tree into a tree of full trees! *)
val treetree = treemap makeFullTree
You may at some point want to fold a tree, too.
I am often told that using the Lazy module in OCaml, one can do everything you can do in a lazy language such as Haskell. To test this claim, I'm trying to write a function that converts a regular list into a static doubly linked list in ocaml.
type 'a dlist = Dnil | Dnode of 'a dlist * 'a * 'a dlist
Given this type I can create several static doubly linked lists by hand:
let rec l1 = Dnode (Dnil,1,l2)
and l2 = Dnode (l1,2,l3)
and l3 = Dnode (l2,3,Dnil)
but I'd like to write a function of type 'a list -> 'a dlist that given any list builds a static doubly linked list in OCaml. For example given [1;2;3] it should output something equivalent to l1 above.
The algorithm is pretty straightforward to write in Haskell:
data DList a = Dnil | Dnode (DList a) a (DList a)
toDList :: [a] -> DList a
toDList l = go Dnil l
where
go _ [] = Dnil
go h (x:xs) = let r = Dnode h x (go r xs) in r
but I haven't been able to figure out where to place calls to lazy to get this to compile in OCaml.
If you build your linked list in right-to-left order (as for normal lists), then the left element of every node will only be built after that node itself is built. You need to represent this by making the left element lazy, which means "this value will be constructed later" :
type 'a dlist =
| Dnil
| Dnode of 'a dlist Lazy.t * 'a * 'a dlist
Once you have this, construct every node as a lazy value using a recursive definition which passes the lazy (still unconstructed) node to the function call that builds the next node (so that it has access to the previous node). It's actually simpler than it looks :
let dlist_of_list list =
let rec aux prev = function
| [] -> Dnil
| h :: t -> let rec node = lazy (Dnode (prev, h, aux node t)) in
Lazy.force node
in
aux (Lazy.lazy_from_val Dnil) list
You can only build a cyclic immutable strict data structure of a shape that's determined at compile time. I'm not going to define or prove this formally, but intuitively speaking, once the data structure is created, its shape isn't going to change (because it's immutable). So you can't add to a cycle. And if you create any element of the cycle, you need to create all the other elements of the cycle at the same time, because you can't have any dangling pointer.
Ocaml can do what Haskell can do, but you do have to get the Lazy module involved! Unlike Haskell's, ML's data structures are strict unless otherwise specified. A lazy data structure has pieces of type 'a Lazy.t. (ML's typing is more precise than Haskell on that particular issue.) Lazy data structures allow cycles to be built by having provisionally-dangling pointers (whose linked values are automatically created when the pointer is first dereferenced).
type 'a lazy_dlist_value =
| Dnil
| Dnode of 'a lazy_dlist_value * 'a * 'a lazy_dlist_value
and 'a lazy_dlist = 'a lazy_dlist_value Lazy.t
Another common way to have cyclic data structures is to use mutable nodes. (In fact, die-hard proponents of strict programming might see lazy data structures as a special case of mutable data structures that doesn't break referential transparency too much.)
type 'a mutable_dlist_value =
| Dnil
| Dnode of 'a mutable_dlist_value * 'a * 'a mutable_dlist_value
and 'a mutable_dlist = 'a mutable_dlist_value ref
Cyclic data structures are mostly useful when they involve at least one mutable component, one function (closure), or sometimes modules. But there'd be no reason for the compiler to enforce that — cyclic strict immutable first-order data structures are just a special case which can occasionally be useful.
type 'a dlist = Dnil | Dnode of 'a dlist Lazy.t * 'a * 'a dlist Lazy.t
let rec of_list list = match list with
[] -> Dnil
| x :: [] ->
let rec single () = Dnode (lazy (single ()), x, lazy (single ()))
in single ()
| x :: y -> Dnode (
lazy (
of_list (match List.rev list with
[] | _ :: [] -> assert false
| x :: y -> x :: List.rev y
)
),
x,
lazy (
of_list (match list with
[] | _ :: [] -> assert false
| x :: y -> y # x :: []
)
)
)
let middle dlist = match dlist with
Dnil -> raise (Failure "middle")
| Dnode (_, x, _) -> x
let left dlist = match dlist with
Dnil -> raise (Failure "left")
| Dnode (x, _, _) -> Lazy.force x
let right dlist = match dlist with
Dnil -> raise (Failure "right")
| Dnode (_, _, x) -> Lazy.force x