nested lists in ocaml - ocaml

I am new to Ocaml and have defined nested lists as follows:
type 'a node = Empty | One of 'a | Many of 'a node list
Now I want to define a wrapping function that wraps square brackets around the first order members of a nested list. For ex. wrap( Many [ one a; Many[ c; d]; one b; one e;] ) returns Many [Many[one a; Empty]; Many[Many[c;d]; Empty]; Many[b; Empty]; Many[e; Empty]].
Here's my code for the same:
let rec wrap list = function
Empty -> []
| Many[x; y] -> Many [ Many[x; Empty]; wrap y;];;
But I am getting an error in the last expression : This expression has the type 'a node but an expression was expected of the type 'b list. Please help.

Your two matches are not returning values of the same type. The first statement returns a b' list; the second statement returns an 'a node. To get past the type checker, you'll need to change the first statement to read as: Empty -> Empty.
A second issue (which you will run into next) is that your recursive call is not being fed a value of the correct type. wrap : 'a node -> 'a node, but y : 'a node list. One way to address this would be to replace the expression with wrap (Many y).
There will also be in issue in that your current function assumes the Many list only has two elements. I think what you want to do is Many (x::y). This matches x as the head of the list and y as the tail. However, you will then need a case to handle Many ([]) so as to avoid infinite recursion.
Finally, the overall form of your function strikes me as a bit unusual. I would replace function Empty -> ... with match list with | Empty -> ....

Related

Eliminate consecutive duplicates of list elements ocaml

I am working on "99 Ocaml Problems" and in the solution, I see this pattern matching:
let rec compress (mylist : 'a list) : 'a list = match mylist with
|a::(b::_ as t) -> if a = b then compress t else a::compress t
|smaller -> smaller
I understand that for the first matching case, if element a is the same as element b, then I move on to the list t. If not, I will append element a to the list of compressing t.
For the second matching case, I am not sure what is the type of "smaller".
When I try to put a square bracket around it since I am thinking the author wants to match second case with one element list, but I have a non-exhaustive pattern.
Can you explain to me what the "smaller" is in this case?
The variable smaller is an 'a list. It matches anything that doesn't match the earlier branch, i.e., a list with one element or the empty list.
Another way to write the compress function without smaller:
let rec compress (mylist : 'a list) : 'a list = match mylist with
| a::(b::_ as t) -> if a = b then compress t else a::compress t
| _ -> mylist;;
Which says the same as the answer of user tbrk : if mylist does not match the first expression, then compress mylist returns mylist.

SML [circularity] error when doing recursion on lists

I'm trying to built a function that zips the 2 given function, ignoring the longer list's length.
fun zipTail L1 L2 =
let
fun helper buf L1 L2 = buf
| helper buf [x::rest1] [y::rest2] = helper ((x,y)::buf) rest1 rest2
in
reverse (helper [] L1 L2)
end
When I did this I got the error message:
Error: right-hand-side of clause doesn't agree with function result type [circularity]
I'm curious as of what a circularity error is and how should I fix this.
There are a number of problems here
1) In helper buf L1 L2 = buf, the pattern buf L1 L2 would match all possible inputs, rendering your next clause (once debugged) redundant. In context, I think that you meant helper buf [] [] = buf, but then you would run into problems of non-exhaustive matching in the case of lists of unequal sizes. The simplest fix would be to move the second clause (the one with x::rest1) into the top line and then have a second pattern to catch the cases in which at least one of the lists are empty.
2) [xs::rest] is a pattern which matches a list of 1 item where the item is a nonempty list. That isn't your attention. You need to use (,) rather than [,].
3) reverse should be rev.
Making these changes, your definition becomes:
fun zipTail L1 L2 =
let
fun helper buf (x::rest1) (y::rest2) = helper ((x,y)::buf) rest1 rest2
| helper buf rest1 rest2 = buf
in
rev (helper [] L1 L2)
end;
Which works as intended.
The error message itself is a bit hard to understand, but you can think of it like this. In
helper buf [x::rest1] [y::rest2] = helper ((x,y)::buf) rest1 rest2
the things in the brackets on the left hand side are lists of lists. So their type would be 'a list list where 'a is the type of x. In x::rest1 the type of rest1 would have to be 'a list Since rest1 also appears on the other side of the equals sign in the same position as [x::rest1] then the type of rest1 would have to be the same as the type of [x::rest1], which is 'a list list. Thus rest1 must be both 'a list and 'a list list, which is impossible.
The circularity comes from if you attempt to make sense of 'a list list = 'a list, you would need a type 'a with 'a = 'a list. This would be a type whose values consists of a list of values of the same type, and the values of the items in that list would have to themselves be lists of elements of the same type ... It is a viscous circle which never ends.
The problem with circularity shows up many other places.
You want (x::rest1) and not [x::rest1].
The problem is a syntactic misconception.
The pattern [foo] will match against a list with exactly one element in it, foo.
The pattern x::rest1 will match against a list with at least one element in it, x, and its (possibly empty) tail, rest1. This is the pattern you want. But the pattern contains an infix operator, so you need to add a parenthesis around it.
The combined pattern [x::rest1] will match against a list with exactly one element that is itself a list with at least one element. This pattern is valid, although overly specific, and does not provoke a type error in itself.
The reason you get a circularity error is that the compiler can't infer what the type of rest1 is. As it occurs on the right-hand side of the :: pattern constructor, it must be 'a list, and as it occurs all by itself, it must be 'a. Trying to unify 'a = 'a list is like finding solutions to the equation x = x + 1.
You might say "well, as long as 'a = 'a list list list list list ... infinitely, like ∞ = ∞ + 1, that's a solution." But the Damas-Hindley-Milner type system doesn't treat this infinite construction as a well-defined type. And creating the singleton list [[[...x...]]] would require an infinite amount of brackets, so it isn't entirely practical anyways.
Some simpler examples of circularity:
fun derp [x] = derp x: This is a simplification of your case where the pattern in the first argument of derp indicates a list, and the x indicates that the type of element in this list must be the same as the type of the list itself.
fun wat x = wat [x]: This is a very similar case where wat takes an argument of type 'a and calls itself with an argument of type 'a list. Naturally, 'a could be an 'a list, but then so must 'a list be an 'a list list, etc.
As I said, you're getting circularity because of a syntactic misconception wrt. list patterns. But circularity is not restricted to lists. They're a product of composed types and self-reference. Here's an example without lists taken from Function which applies its argument to itself?:
fun erg x = x x: Here, x can be thought of as having type 'a to begin with, but seeing it applied as a function to itself, it must also have type 'a -> 'b. But if 'a = 'a -> 'b, then 'a -> b = ('a -> 'b) -> 'b, and ('a -> 'b) -> b = (('a -> 'b) -> b) -> b, and so on. SML compilers are quick to determine that there are no solutions here.
This is not to say that functions with circular types are always useless. As newacct points out, turning purely anonymous functions into recursive ones actually requires this, like in the Y-combinator.
The built-in ListPair.zip
is usually tail-recursive, by the way.

How to define a data structure for a list that cannot be empty in F#?

Recently, I started learning F# and I am struggling to work with discriminated unions, lists en structures. I'd found an exercise where I need to do the following:
'Define a NonEmptyList<'a> data structure which can represent a list which can never be empty'
Attempt
let NonEmptyList (input : List<'a>) =
match input with
| [] -> failwith "List canot be empty"
| [x] -> x
Not really sure if this is correctly implemented with the let-keyword. I.e... do I need this construction perhaps:
type NonEmptyList<'a> = struct
| List
edit 1
type NonEmptyList<'T> =
| Cons of 'T * List<'T>
| Single of List<'T>
edit 2
let list1 : NonEmptyList<'T> = Single[1..10]
let list2 : NonEmptyList<'T> = Cons([1..3],[1..3])
I am receiving a parser error: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrianed to be type 'a list.
First of all, my reading of the task is to give a type definition (using type) rather than a function that checks whether a list is empty.
To solve this, it's best to first understand normal F# lists:
type List<'T> =
| Cons of 'T * List<'T>
| Empty
Here, a list is either empty (represented by the Empty value) or it contains a value of type 'T followed by another list represented by List<'T>. This way, you can create:
let nop = Empty // Empty list
let oneTwo = Cons(1, Cons(2, Empty)) // List containing 1 and 2
So, to answer the question, you will need a very similar definition to the one for List<'T>, except that it should not be possible to create an Empty list. You can start with something like this:
type NonEmptyList<'T> =
| Cons of 'T * NonEmptyList<'T>
Now that I removed Empty, we can no longer create empty lists - but this does not quite do the trick, because now you can never end any list. I won't give a full answer to avoid spoilers as I think figuring this out is the point of the exercise, but you will need something like:
type NonEmptyList<'T> =
| Cons of 'T * NonEmptyList<'T>
| // One more case here
What can the last case be, so that it does not contain another List<'T> (and thus lets us end a list), but is not Empty, so that we cannot create empty lists?
A non-empty list consists of a head and an optional non-empty tail. You can represent such a type as a single-case union:
type NEL<'a> = NEL of 'a * NEL<'a> option
let l = NEL(1, Some(NEL(2, None)))
or a record type:
type NEL<'a> = {head : 'a; tail : NEL<'a> option}
let l = { head = 1; tail = Some({head = 2; tail = None})}

Creating a tree using recursion

I am trying to create a tree from an int list in OCAML. I am very new to functional programming. This is my function so far:
let rec theList (lst : int list) =
match lst with
| [] -> Empty
| h::t -> insert Empty h::theList List.tl lst
when insert is a function that creates a node and puts the value of h in the node. I try to traverse through the list but at the colons after I call insert with the arguments I get the error: "Error: The variant type bstTree has no constructor ::" as this a type I defined as:
type bstTree = Empty | bstTree * Node of int * bstTree
In a broad sense all I am trying to do is recurse through the list and call insert on each int in the list. I have been working on this for awhile now so any help is appreciated, thank you.
There are many problems with your code (to be expected if you're just starting out).
First, your type definition is not syntactically valid:
# type bstTree = Empty | bstTree * Node of int * bstTree;;
Error: Syntax error
Most likely you want something more like this:
type bstTree = Empty | Node of bstTree * int * bstTree
Second, you're defining a function named theList, but inside the function you call a function named fromList. I have a suspicion that these are supposed to be the same name.
Third, there is no need to call List.tl since you have already matched the tail of the list under the name t.
Fourth, you are going to need more parentheses in your expression. A good starting point might be something like this:
insert Empty h (fromList List.tl lst)
As the compiler is pointing out, you can't apply the constructor :: to values of type bstTree. The :: constructor only works for building a list from an element and another (smaller) list.

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.