I am compiling an ocaml project on my linux machine I am getting this error
The function applied to this argument has type
?eq:('week4 -> 'week4 -> bool ) -> bool
This argument cannot be applied without label.
Here is the code
let rec reduceandor (ee: e_expression) : e_expression =
match ee with
| EE_loc_function_EEL (ll, f, eel) ->
fail "EE_loc_function_EEL, reduceandor, transform2.ml"
| EE_function_EEL (f, eel) when (f = Function.AND) || (f = Function.OR) ->
(* https://stackoverflow.com/a/30634912/702977 *)
let uniq_cons x xs = if List.mem (fun ee0 ee1 -> ee0 = ee1) x xs then xs else x :: xs in
let remove_from_right xs = List.fold_right uniq_cons xs [] in
let eel_wo_duplicates = remove_from_right eel in
if List.length eel_wo_duplicates = 1
then List.nth eel_wo_duplicates 0
else EE_function_EEL (f, eel_wo_duplicates)
| _ ->
ee
The error is in this line
let uniq_cons x xs = if List.mem (fun ee0 ee1 -> ee0 = ee1) x xs then xs else x :: xs
The issue is when I compile the project on a mac machine everything works just fine.
The ocaml version on both machine is: 4.07.1
Opam version : 2.0.2
I assume you are using an alternative standard library that hides the original implementation of List.mem. As the error indicates, you need the equality predicate to be associated with a label, like this:
List.mem ~eq:(fun ee0 ee1 -> ee0 = ee1) x xs
Related
When declaring a function, I've 3 different ways:
let f x = ...
let f = (fun x -> ...)
let f = function
| ... -> (pattern matching)
It's this last one that I don't fully understand how it works.
I was doing a function that, considering a list (we'll assume it has integers in it but could be anything), reverses it, pretty basic, but with a complexity of O(n). After struggling for an hour at least I check the answer, and it is written like this:
let reverse lst =
let rec aux acc = function
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
I thought that using the key word function was just another way of doing patter matching, but when I do this:
let reverse lst =
let rec aux acc =
match aux with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
It doesn't work, and idk why. On top of that, why can we add tl at the end of the first function? Isn't aux a single argument function?
There are a few problems with this question. First, the code you give as the solution for reverse is not valid OCaml. It matches aux (which is a function) against list patterns. Most likely aux was supposed to be acc. But even so it doesn't seem right because it should have two arguments (the accumulated result and the input that still needs to be processed).
Second, your two code examples are the same. You seem to be saying that one works and one doesn't work. That doesn't make sense since they're the same.
IMHO you need to rewrite the question if you want to get a helpful answer.
Ocaml uses currying, which means that a two-argument function is the same thing that a function whose return value is a function.
To define a two-argument function, you can combine all the ways you know of creating one-argument functions:
let f x y = x + y
let f x = (fun y -> x + y)
let f x = function
| y -> x + y
let f = (fun x -> (fun y -> x + y))
let f = function
| x -> function
| y -> x + y
let f x = (let g y = x + y in g)
etc, etc.
All these definitions for f lead to the same result:
val f : int -> int -> int = <fun>
# f 3 4;;
- : int = 7
Note that the signature of f is:
val f : int -> int -> int = <fun>
If we added parentheses to better understand this signature, it would be this:
val f : int -> (int -> int) = <fun>
Meaning that f is a one-argument function whose return value is a one-argument function whose return value is an int.
Indeed, if we partially apply f:
# f 3;;
- : int -> int = <fun>
# let add_three = f 3;;
val add_three : int -> int = <fun>
# add_three 4;;
- : int = 7
The code you give at the end of your question is wrong. It's most likely intended to be this:
let reverse lst =
let rec aux acc l =
match l with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst;;
val reverse : 'a list -> 'a list = <fun>
# reverse [1;2;3;4;5];;
- : int list = [5; 4; 3; 2; 1]
Background
We are implementing this algorithm in F#.
Here is a little bit more information from Topor (1982) about the notation that the algorithm uses:
Formally, a 't list is either null (denoted nil) or has a hd (which is a 't) and a tl (which is a 't list)... If x is a list, we test whether it is null by writing null x... We create a new list, adding the element a at the front of an existing list x, by writing a:x... We denote the unit list containing the element a by list(a)... list(x) = x:nil.
Question
What we're wondering is how in F# to express those nil, null, and list(nil) values. For instance, should we be using the Option type, an empty list, or something else?
What We Have Tried
let rec kpermute k (xs: 't list) =
let rec mapPerm k xs ys =
match ys with
| [] -> []
| head::tail ->
let kpermuteNext = kpermute (k-1) (removeFirst head xs)
let mapPermNext = mapPerm k xs tail
mapcons head kpermuteNext mapPermNext
match k with
| 0 -> [[]]
| _ when xs.Length < k -> []
| _ -> mapPerm k xs xs
When working with lists, for list(nil) we use [[]] and for nil we use []. While that's fine, there might be a more expressive way to do it. There are also times when we use List.empty<'t list> and List.empty<'t> when the type inference needs more information.
The paper gives you all the answers: nil is []; null x is a test for whether x is the empty list; list(nil) is [[]].
The naïve translation of algorithm B to F# is as follows:
let rec minus a = function
| [] -> failwith "empty list"
| xh :: xt -> if xh = a then xt else xh :: minus a xt
let rec permute2 k x =
if k = 0 then [[]]
elif List.length x < k then []
else mapperm k x x
and mapperm k x = function
| [] -> []
| yh :: yt -> mapcons yh (permute2 (minus yh x)) (mapperm x yt)
and mapcons a ps qs =
match ps with
| [] -> qs
| ph :: pt -> a :: ph :: mapcons a pt qs
I just looking for a little advice, how to rewrite code using tail recursion
open Core.Std;;
let rec dig x =
match x with
| 0 -> []
| _ -> x :: dig (x - 1)
;;
let () =
let numbers = dig 10 in
List.iter ~f:(Printf.printf "%d, ") numbers;
Printf.printf "\n";
;;
Any advice will be helpful
let dig x =
let rec f x s =
match x with
| 0 -> s
| _ -> f (x-1) (x::s)
f x []
Is this what you want? It's using tail recursion.
Edit:
for a decreasing seq, just replace (x::s) with (List.append s [x]) or (s # [x]) but it's NOT a good idea,and List.rev is better:
let dig x =
let rec f x s =
match x with
| 0 -> s
| _ -> f (x-1) (s # [x])
f x []
let dig x =
let rec f s z =
if z = x then s
else f (z::s) (z+1)
in
f [] 0
not sure if this floats your boat: You may have to tweak the border cases depending if you want 0 or the starting number included.
If you don't want to use List.rev after building the list backwards (which in my opinion is perfectly fine), nor starting your recursion with 0 instead of n, you can use some kind of continuation:
let dig2 x =
let rec aux x kont =
match x with
| 0 -> kont
| _ -> aux (x-1) (fun l -> kont (x::l))
in
aux x (fun l -> l) [];;
Basically each step returns a function that, given the list built by the remaining steps, will append x to it. We start the recursion with the identity function since we don't have anything to build yet. Then, when we exit from the recursion, we thus just have to apply the empty list to the obtained function.
Well, it seems to can have multiple solutions
open Core.Std;;
let rec digtail ?(l=[]) x =
match x with
| 0 -> l
| _ -> digtail ~l: (l # [x]) (x - 1)
;;
let () =
let numbers = digtail 10 in
List.iter ~f:(Printf.printf "%d, ") numbers;
Printf.printf "\n";
;;
Thanks to all, you helped a lot.
Is there a library function to find List1 minus elements that appear in List2? I've been googling around and haven't found much.
It doesn't seem too trivial to write it myself. I've written a function to remove a specific element from a list but that's much more simple:
let rec difference l arg = match l with
| [] -> []
| x :: xs ->
if (x = arg) then difference xs arg
else x :: difference xs arg;;
Will this do?
let diff l1 l2 = List.filter (fun x -> not (List.mem x l2)) l1
What I ended up actually doing was just writing another function which would call the first one I posted
let rec difference l arg = match l with
| [] -> []
| x :: xs ->
if (x = arg) then difference xs arg
else x :: difference xs arg;;
let rec list_diff l1 l2 = match l2 with
| [] -> l1
| x :: xs -> list_diff (difference l1 x) xs;;
Although the solution I accepted is much more elegant
Suppose I have some code like this:
List.map (fun e -> if (e <> 1) then e + 1 else (*add nothing to the list*))
Is there a way to do this? If so, how?
I want to both manipulate the item if it matches some criteria and ignore it if it does not. Thus List.filter wouldn't seem to be the solution.
SML has a function mapPartial which does exactly this. Sadly this function does not exist in OCaml. However you can easily define it yourself like this:
let map_partial f xs =
let prepend_option x xs = match x with
| None -> xs
| Some x -> x :: xs in
List.rev (List.fold_left (fun acc x -> prepend_option (f x) acc) [] xs)
Usage:
map_partial (fun x -> if x <> 1 then Some (x+1) else None) [0;1;2;3]
will return [1;3;4].
Or you can use filter_map from extlib as ygrek pointed out.
Both Batteries and Extlib provide an equivalent of mapPartial: their extended List module sprovide a filter_map function of the type ('a -> 'b option) -> 'a list -> 'b list, allowing the map function to select items as well.
Another solution would be to use directly a foldl :
let f e l = if (e <> 1)
then (e + 1)::l
else l
in List.fold_left f [] list
But my preference is filter_map as Michael Ekstrand provided
Alternatively you can filter your list then apply the map on the resulted list as follows :
let map_bis predicate map_function lst =
List.map map_function (List.filter predicate lst);;
# val map_bis : ('a -> bool) -> ('a -> 'b) -> 'a list -> 'b list = <fun>
Usage :
# map_bis (fun e -> e<>1) (fun e -> e+1) [0;1;2;3];;
- : int list = [1; 3; 4]
You can also map values to singleton lists if you want to keep them or empty lists if you don't, and then concat the results.
List.concat (List.map (fun e -> if (e <> 1) then [e + 1] else []) my_list)
use
let rec process = function
| 1 :: t -> process t
| h :: t -> (h + 1) :: (process t)
| [] -> []
or tail recursive
let process =
let rec f acc = function
| 1 :: t -> f acc t
| h :: t -> f ((h + 1) :: acc) t
| [] -> List.rev acc in
f []
or with a composition of standard functions
let process l =
l |> List.filter ((<>)1)
|> List.map ((+)1)
The OCaml standard library has had List.filter_map since 4.08. This can therefore now be written as:
List.filter_map (fun e -> if e <> 1 then Some (e + 1) else None)