How to properly use guards in Haskell? - list

I'm new to Haskell and I'm trying to write simple functions to get myself used to the syntax, I want to write my own function for adding a certain element to a list at a specific index. Here's what I wrote in Atom (my text editor):
addElem :: a->[a]->Int->[a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = a ++ (elem:b) where a = take index list; b = drop index list
| otherwise = list
The idea is that it won't freak out as long as index is an Int and elem is of the same type as the elements of list, but when I try to load this into ghci I get "parse error on `|'." Do I need to constrain the types of the arguments? I'm reading Learn You A Haskell but I haven't gotten to the part where they fully explain how the indentations work, so my error might also be there.

where blocks need to occur at the end of the whole function, and are shared amongst all the cases. You probably meant to use a let:
addElem :: a -> [a] -> Int -> [a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = let a = take index list; b = drop index list in a ++ (elem:b)
| otherwise = list
Also, note that let could be written more concisely as let (a,b) = splitAt index list in .... splitAt is also in the Prelude. Of course, you could also just move the where block to the end of the function (Haskell's laziness makes this easy to reason about).
addElem :: a -> [a] -> Int -> [a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = a ++ (elem:b)
| otherwise = list
where
a = take index list
b = drop index list
Personally, I like this less because it suggests that a and b may be used elsewhere in the function.
Section 4.4.3 of the 2010 Haskell Report goes into more detail on where where is allowed.

Related

Insert number into sorted list using List.fold_right

I am trying to insert a number x into a sorted list l using Ocaml's List.fold_right and return the list with the inserted element. I have figured out a way to insert it if the element is to go at the front of the list or in the middle of the list, however I cannot figure out how to code the case where the element is larger than every element in the list and thus must go at the end.
Here is what I have so far:
let insert_number (x: int) (l: int list): int list =
List.fold_right l ~f:(
fun cur -> fun acc ->
if x < cur then cur::x::accum
else cur::accum
) ~init: []
Using this with a test case like:
insert_number (3) ([1; 2; 4]);;
- : int list = [1; 2; 3; 4]
gives the correct answer. However, with a test case like this:
insert_number (3) ([1; 2]);;
- : int list = [1; 2]
the number is not inserted because it should be added to the end of the list.
Could someone help me understand how I am supposed to integrate this case into the function used with List.fold_right.
A fold works by passing along a set of state as it iterates over each element in a list (or other foldable data structure). The function passed in takes both the current element and that state.
I think you're really really close, but you need as Jeffrey suggests a boolean flag to indicate whether or not the value has been inserted. This will prevent multiple insertions and if the flag is still false when the fold is done, we can detect that and add the value to insert.
This match also serves the purpose of giving us an opportunity to discard the no longer needed boolean flag.
let insert v lst =
match List.fold_right
(fun x (inserted, acc) ->
if v > x && not inserted then (true, x::v::acc)
else (inserted, x::acc))
lst
(false, []) with
| (true, lst) -> lst
| (_, lst) -> v::lst
One way to look at List.fold_right is that it looks at each element of the list in turn, but in reverse order. For each element it transforms the current accumulated result to a new one.
Thinking backward from the end of the list, what you want to do, in essence, is look for the first element of the list that's less than x, then insert x at that point.
So the core of the code might look something like this:
if element < x then element :: x :: accum else element :: accum
However, all the earlier elements of the list will also be less than x. So (it seems to me) you need to keep track of whether you've inserted x into the list or not. This makes the accumulated state a little more complicated.
I coded this up and it works for me after fixing up the case where x goes at the front of the list.
Perhaps there is a simpler way to get it to work, but I couldn't come up with one.
As I alluded to in a comment, it's possible to avoid the extra state and post-processing by always inserting the element and effectively doing a "local sort" of the last two elements:
let insert_number x l =
List.fold_right (
fun cur -> function
| [] when x > cur -> [cur; x]
| [] -> [x; cur]
| x::rest when x > cur -> cur::x::rest
| x::rest -> x::cur::rest
) l []
Also, since folding doesn't seem to actually be a requirement, here's a version using simple recursion instead, which I think is far more comprehensible:
let rec insert_number x = function
| [] -> [x]
| cur::rest when cur > x -> x::cur::rest
| cur::rest -> cur::insert_number x rest

ocaml list to array array

I'm trying to convert a list with a specified width to array array.
For example, i want to convert this :
int list = [97; 114; 110; 97; 117; 100; 2]
to
int array array = [| [|97; 114; 110|]; [|97; 117; 100|]; [|2; 0; 0|] |]
I am not used to ocaml so I tried to use this code :
let split list width =
let rec aux i acc = function
| [] -> List.rev acc, []
| h :: t as l ->
if i = 0
then List.rev acc, l
else aux (i-1) (h :: acc) t in
aux width [] list;;
If you want to code in a language you have to get used to it :) You have to spend a couple of hours and read at least the intoduction to OCaml. The first chapter would be enough to be able to solve your example.
In your particular example, (which I took the liberty to reindent, to make it more readable), the variable n in aux n [] list is unbound. Indeed, what n is supposed to mean? Another tip, is that the width parameter of your function is not used in the body of your function. You probably already get it... but do not rush to fix it. First, read the introductory course to OCaml :)
I would work backwards on this problem.
First I would create a function which takes a list, a padding value and the number of times that padding must be applied. Something like this:
val add_padding: int -> int -> int list -> int list
Next I would create a function which takes a list and a width and returns a new list and the remainder of the list passed in... This should fail if the passed in list is too short. Something like:
val create_new_list: int -> 'a list -> 'a list * 'a list
With these two functions, you should be able to split your input list.

How to double elements in an F# list and set them in a new list

I am very new to F# and functional programming in general, and would like to recursively create a function that takes a list, and doubles all elements.
This is what I used to search for a spacific element, but im not sure how exactly I can change it to do what I need.
let rec returnN n theList =
match n, theList with
| 0, (head::_) -> head
| _, (_::theList') -> returnN (n - 1) theList'
| _, [] -> invalidArg "n" "n is larger then list length"
let list1 = [5; 10; 15; 20; 50; 25; 30]
printfn "%d" (returnN 3 list1 )
Is there a way for me to augment this to do what I need to?
I would like to take you through the thinking process.
Step 1. I need a recursive function that takes a list and doubles all the elements:
So, let's implement this in a naive way:
let rec doubleAll list =
match list with
| [] -> []
| hd :: tl -> hd * 2 :: doubleAll tl
Hopefully this logic is quite simple:
If we have an empty list, we return another empty list.
If we have a list with at least one element, we double the element and then prepend that to the result of calling the doubleAll function on the tail of the list.
Step 2. Actually, there are two things going on here:
I want a function that lets me apply another function to each element of a list.
In this case, I want that function to be "multiply by 2".
So, now we have two functions, let's do a simple implementation like this:
let rec map f list =
match list with
| [] -> []
| hd :: tl -> f hd :: map f tl
let doubleAll list = map (fun x -> x * 2) list
Step 3. Actually, the idea of map is such a common one that it's already built into the F# standard library, see List.map
So, all we need to do is this:
let doubleAll list = List.map (fun x -> x * 2) list

Asking about return type, list and set data structure in OCaml

I have a function compute a list to boolean matrix where num_of_name: 'a list -> 'a -> int : return a position of element in a list.
1) I would like mat_of_dep_rel : 'a list -> bool array array.
My problem is that from the first List.iter it should take a list l and not an empty list []. But if I return l instead of [], it will give me a type: ('a * 'a list) list -> boolean array array. Which is not what I want.
I would like to know how can I return mat_of_dep_rel: 'a list -> bool array array?
let mat_of_dep_rel l =
let n = List.length l in
let m = Array.make_matrix n n false in
List.iter (fun (s, ss) ->
let i = num_of_name ss s in
List.iter (fun t ->
m.(i).( num_of_name ss t) <- true) ss) [];
m;;
2) I have another functions compute equivalence classes, to compute an equivalence class : check an element i if it has a path i -> j and j -> i or itself. I would like it return for me a type int list list. In this code I force the return type 'list list by put j in [j]. My question is:
Is it correct if I force like that? If not how can I return the type I want int list list.
let eq_class m i =
let mi = m.(i) in
let aux =
List.fold_right (fun j l ->
if j = i || mi.(j) && m.(j).(i) then
[j] :: l else l) in
aux [] [];;
Another function eq_classes compute a set of equivalence classes by collect all the equivalence class. I would like to use a list data structure more than using a set. But for the moment, I am not really understand about the code saying here.
Could you please explain for me? If I want to use a list data structure, how can I use it? What is a different between a list and a set data structure in OCaml? Advance/Disadvance of its?
let eq_classes m =
IntSet.fold (fun i l -> IntMap.add i (eq_class m i) l)
IntSet.empty IntMap.empty;;
3) My last question is that. After having all the equivalence classes I would like to sort them. I have another functions
let cmp m i j = if eq_class m i = eq_class m j then 0
else if m.(i).(j) then -1 else 1;;
let eq_classes_sort m l = List.sort (cmp m) l;;
for the last function I want it return for me bool array array -> int list list not bool array array -> int list -> int list
Thank you for your help.
There are quite many things wrong or obscure about your questions, but I'll try to answer as well as possible.
Question 1
You're apparently trying to transform the representation of a dependency graph from a list to a matrix. It does not make any kind of sense to have a dependency graph represented as 'a list (in fact, there is no interesting way to build a boolean matrix from an arbitrary list anyway) so you probably intended to use an (int * int) list of pairs, each pair (i,j) being a dependency i -> j.
If you instead have a ('a * 'a) list of arbitrary pairs, you can easily number the elements using your num_of_name function to turn it into the aforementioned (int * int) list.
Once you have this, you can easily construct a matrix :
let matrix_of_dependencies dependencies =
let n = List.fold_left (fun (i,j) acc -> max i (max j acc)) 0 dependencies in
let matrix = Array.make_matrix (n+1) (n+1) false in
List.iter (fun (i,j) -> matrix.(i).(j) <- true) dependencies ;
matrix
val matrix_of_dependencies : (int * int) list -> bool array array
You can also compute the parameter n outside the function and pass it in.
Question 2
An equivalence class is a set of elements that are all equivalent. A good representation for a set, in OCaml, would be a list (module List) or a set (module Set). A list-of-lists is not a valid representation for a set, so you have no reason to use one.
Your algorithm is obscure, since you're apparently performing a fold on an empty list, which will just return the initial value (an empty list). I assume that you intended to instead iterate over all entries in the matrix column.
let equivalence_class matrix element =
let column = matrix.(element) and set = ref [] in
Array.iteri begin fun element' dependency ->
if dependency then set := element' :: !set
end column ;
!set
val equivalence_class : bool array array -> int list
I only check for i -> j because, if your dependencies are indeed an equivalence relationship (reflexive, transitive, symmetrical), then i -> j implies j -> i. If your dependencies are not an equivalence relationship, then you are in fact looking for cycles in a graph representation of a relationship, which is an entirely different algorithm from what you suggested, unless you compute the transitive closure of your dependency graph first.
Sets and lists are both well-documented standard modules, and their documentation is freely available online. Ask questions on StackOverflow if you have specific issues with them.
You asked us to explain the piece of code you provide for eq_classes. The explanation is that it folds on an empty set, so it returns its initial value - an empty map. It is, as such, completely pointless. A more appropriate implementation would be:
let equivalence_classes matrix =
let classes = ref [] in
Array.iteri begin fun element _ ->
if not (List.exists (List.mem element) !classes) then
classes := equivalence_class matrix element :: !classes
end matrix ;
!classes
val equivalence_classes : bool array array -> int list list
This returns all the equivalence classes as a list-of-lists (each equivalence class being an individual list).
Question 3
The type system is pointing out that you have defined a comparison function that works on int, so you can only use it to sort an int list. If you intend to sort an int list list (a list of equivalence classes), then you need to define a comparison function for int list elements.
Assuming that (as mentioned above) your dependency graph is transitively closed, all you have to do is use your existing comparison algorithm and apply it to arbitrary representants of each class:
let compare_classes matrix c c` =
match c, c` with
| h :: _, h' :: _ -> if matrix.(h).(h') then 1 else -1
| _ -> 0
let sort_equivalence_classes matrix = List.sort (compare_classes matrix)
This code assumes that 1. each equivalence class only appears once and 1. each equivalence class contains at least one element. Both assumptions are reasonable when working with equivalence classes, and it is a simple process to eliminate duplicates and empty classes beforehand.

Combine Lists with Same Heads in a 2D List (OCaml)

I'm working with a list of lists in OCaml, and I'm trying to write a function that combines all of the lists that share the same head. This is what I have so far, and I make use of the List.hd built-in function, but not surprisingly, I'm getting the failure "hd" error:
let rec combineSameHead list nlist = match list with
| [] -> []#nlist
| h::t -> if List.hd h = List.hd (List.hd t)
then combineSameHead t nlist#uniq(h#(List.hd t))
else combineSameHead t nlist#h;;
So for example, if I have this list:
[[Sentence; Quiet]; [Sentence; Grunt]; [Sentence; Shout]]
I want to combine it into:
[[Sentence; Quiet; Grunt; Shout]]
The function uniq I wrote just removes all duplicates within a list. Please let me know how I would go about completing this. Thanks in advance!
For one thing, I generally avoid functions like List.hd, as pattern maching is usually clearer and less error-prone. In this case, your if can be replaced with guarded patterns (a when clause after the pattern). I think what is happening to cause your error is that your code fails when t is []; guarded patterns help avoid this by making the cases more explicit. So, you can do (x::xs)::(y::ys)::t when x = y as a clause in your match expression to check that the heads of the first two elements of the list are the same. It's not uncommon in OCaml to have several successive patterns which are identical except for guards.
Further things: you don't need []#nlist - it's the same as just writing nlist.
Also, it looks like your nlist#h and similar expressions are trying to concatenate lists before passing them to the recursive call; in OCaml, however, function application binds more tightly than any operator, so it actually appends the result of the recursive call to h.
I don't, off-hand, have a correct version of the function. But I would start by writing it with guarded patterns, and then see how far that gets you in working it out.
Your intended operation has a simple recursive description: recursively process the tail of your list, then perform an "insert" operation with the head which looks for a list that begins with the same head and, if found, inserts all elements but the head, and otherwise appends it at the end. You can then reverse the result to get your intended list of list.
In OCaml, this algorithm would look like this:
let process list =
let rec insert (head,tail) = function
| [] -> head :: tail
| h :: t ->
match h with
| hh :: tt when hh = head -> (hh :: (tail # t)) :: t
| _ -> h :: insert (head,tail) t
in
let rec aux = function
| [] -> []
| [] :: t -> aux t
| (head :: tail) :: t -> insert (head,tail) (aux t)
in
List.rev (aux list)
Consider using a Map or a hash table to keep track of the heads and the elements found for each head. The nlist auxiliary list isn't very helpful if lists with the same heads aren't adjacent, as in this example:
# combineSameHead [["A"; "a0"; "a1"]; ["B"; "b0"]; ["A"; "a2"]]
- : list (list string) = [["A"; "a0"; "a1"; "a2"]; ["B"; "b0"]]
I probably would have done something along the lines of what antonakos suggested. It would totally avoid the O(n) cost of searching in a list. You may also find that using a StringSet.t StringMap.t be easier on further processing. Of course, readability is paramount, and I still find this hold under that criteria.
module OrderedString =
struct
type t = string
let compare = Pervasives.compare
end
module StringMap = Map.Make (OrderedString)
module StringSet = Set.Make (OrderedString)
let merge_same_heads lsts =
let add_single map = function
| hd::tl when StringMap.mem hd map ->
let set = StringMap.find hd map in
let set = List.fold_right StringSet.add tl set in
StringMap.add hd set map
| hd::tl ->
let set = List.fold_right StringSet.add tl StringSet.empty in
StringMap.add hd set map
| [] ->
map
in
let map = List.fold_left add_single StringMap.empty lsts in
StringMap.fold (fun k v acc-> (k::(StringSet.elements v))::acc) map []
You can do a lot just using the standard library:
(* compares the head of a list to a supplied value. Used to partition a lists of lists *)
let partPred x = function h::_ -> h = x
| _ -> false
let rec combineHeads = function [] -> []
| []::t -> combineHeads t (* skip empty lists *)
| (hh::_ as h)::t -> let r, l = List.partition (partPred hh) t in (* split into lists with the same head as the first, and lists with different heads *)
(List.fold_left (fun x y -> x # (List.tl y)) h r)::(combineHeads l) (* combine all the lists with the same head, then recurse on the remaining lists *)
combineHeads [[1;2;3];[1;4;5;];[2;3;4];[1];[1;5;7];[2;5];[3;4;6]];;
- : int list list = [[1; 2; 3; 4; 5; 5; 7]; [2; 3; 4; 5]; [3; 4; 6]]
This won't be fast (partition, fold_left and concat are all O(n)) however.