Common Parse error: "in" in a function that call other functions OCaml - list

Well this Parse error: "in" expected after [binding] (in [expr])
is a common error as far I have searched in Ocaml users, but in the examples I saw I didnt found the answer for my error, then I will explain my problem:
I declared this function:
let rec unit_propag xs =
let cuAux = teste xs
let updatelist = funfilter (List.hd(List.hd cuAux)) (xs)
let updatelist2 = filtraelem (negar(List.hd(List.hd cuAux))) (updatelist)
if(not(List.mem [] xs) && (teste xs <> []))
then
unit_propag updatelist2
;;
The functions I am using inside this code were declared before like this:
let funfilter elem xs = List.filter (fun inner -> not (List.mem elem inner)) xs;;
let filtraele elem l = List.map( fun y -> List.filter (fun x -> x <> elem) y)l;;
let teste xs = List.filter(fun inner ->(is_single inner)inner)xs;;
let is_single xs = function
|[_] -> true
|_ -> false
;;
let negar l =
match l with
V x -> N x
|N x -> V x
|B -> T
|T -> B
;;
But not by this order.
Well they were all doing what I wanted to do, but now when I declared unit_propag and tried to compile, I had an error in line of
let cuAux = teste xs
It said:
File "exc.ml", line 251, characters 20-22:
Parse error: "in" expected after [binding] (in [expr])
Error while running external preprocessor
Command line: camlp4o 'exc.ml' > /tmp/ocamlpp5a7c3d
Then I tried to add a ; on the end of each function, and then my "in" error appeared on the line of the last function, is this case unit_propag updatelist2
What I am doing wrong? people usually say that this kind of errors occurs before that code, but when i comment this function the program compiles perfectly.
I need to post more of my code? Or i need to be more clear in my question?
Is that possible to do in Ocaml or I am doing something that I cant?
Thanks

The error message says you're missing in, so it seems strange to solve it by adding ; :-)
Anyway, you're missing the keyword in after all the let keywords in your function unit_propag.
You should write it like this:
let rec unit_propag xs =
let cuAux = teste xs in
let updatelist = funfilter (List.hd(List.hd cuAux)) (xs) in
let updatelist2 =
filtraelem (negar(List.hd(List.hd cuAux))) (updatelist)
in
if (not (List.mem [] xs) && (teste xs <> [])) then
unit_propag updatelist2
The basic issue has been explained many times here (as you note). Basically there are two uses of the keyword let. At the outer level it defines the values in a module. Inside another definition it defines a local variable and must be followed by in. These three lets are inside the definition of unit_propag.
Another attempt to explain the use of let is here: OCaml: Call function within another function.

Related

Head of empty list

I'm trying to make a function which returns a list of the first element of each sub-list, including empty lists being returned as [].
let firstCol (lst: 'a list list) =
List.map List.head lst
This works as long as there are no empty lists, but I get the following error message when my input includes an empty list:
System.ArgumentException: The input list was empty.
How do I go about this? Thanks in advance.
You can use List.tryHead or write your own function from the ground, or with helpers like List.fold/List.foldBack.
If you do List.tryHead you get an option as a result, either Some element, or None if the list is empty. So you must think what happens in the None case. You cannot return an empty list for a sub-list, because a list must have the same type. But you could for example skip empty lists. Or just keep the Option. As it indicates when a list was empty.
let xs = [[1;2;3];[];[4;5;6];[];[7;8;9]]
printfn "%A" (List.map List.tryHead xs)
returning
[Some 1; None; Some 4; None; Some 7]
You could skip the empty sub-lists
printfn "%A" (List.choose List.tryHead xs)
so you get
[1;4;7]
or do it on your own, with List.foldBack
let firstCol xs =
let folder xs acc =
match List.tryHead xs with
| Some x -> x :: acc
| None -> acc
List.foldBack folder xs []
Or even more basic
let rec firstCol xs =
match xs with
| [] -> []
| []::xss -> firstCol xss
| (x::xs)::xss -> x :: firstCol (xss)
The last version is not tail-recursive, but anyway, you should try and train to understand such a recursive definition. And be able to turn such a function into an tail-recursive on your own.
What you're asking for can't be done with the signature you currently have. Consider this input:
[
[1; 2]
[]
[3; 4]
]
It looks like you're asking for the following output:
[
1
[]
3
]
However, that isn't a legal list in F# because its elements don't have the same type.
I think your best bet is just to use tryHead instead, as suggested in the other answers.

trimming a list of pairs with OCaml

I am trying to filter a list of pairs and return a new list containing only the first element of each pair. The input/output should go like this:
input = [('A', 3); ('B', 2); ('D', 1)]
output = ['A'; 'B'; 'D']
The code i have so far is this:
let rec trimList l = function
| [] -> []
| head::tail -> let l' = [fst head] # trimList List.tl l;;
but i get the following error:
Line 3, characters 59-61:
3 | | head::tail -> let l' = [fst (head)] # trimList List.tl l;;
^^
Error: Syntax error
I don't know why this isn't working. I know this is very simple, but i am new to OCaml.
Any help would be appreciated, thank you.
Your syntax problem is caused by the fact that you have let with no corresponding in.
A let expression looks like this:
let v = expr1 in expr2
In essence this establishes a local variable v with value expr1 and has the value of expr2 (which will probably contain instances of the variable v).
You are missing the in part of the let expression.
As another comment, if you define a function like this:
let f l = function ...
You are defining a function of two parameters. There is an implicit parameter defined by the function keyword; the parameter is matched against the following patterns.
Most likely you want to remove the l from you function definition.
There are a few other problems with your code, but I hope this helps to make progress.

Why do i get syntax error at end problem with pattern matching

I have to make a function that takes list a list and returns list of pairs of first and last element,2nd and 2nd last and so forth It doesn't matter if the list has even or odd number of elements because if its odd i will just ignore the middle element.The idea i have is that make a new rec fun that takes old list and its revers as input i think i finished the code but i get Syntax error for ;;
let lip l =
if [] then []
else let l1=l l2=List.rev l in
let rec lp l1 l2 = match l1,l2 with
| [],[] ->[]
| [],h2::t2->[]
| h1::_,h2::_ ->
if (List.length l -2) >= 0 then [(h1,h2)]# lp(List.tl l1) t2
else [] ;;
There are quite a few errors in your code.
I think the specific error you're seeing is caused by the fact that there is no in after let rec lp ....
Every let that's not at the top level of a module needs to be followed by in. One way to think of it is that it's a way of declaring a local variable for use in the expression that appears after in. But you need to have the in expr.
Another way to look at it is that you're defining a function named lp but you're not calling it anywhere.
As #lambda.xy.x points out, you can't say if [] then ... because [] isn't of type bool. And you can't say let x = e1 y = e2 in .... The correct form for this is let x = e1 in let y = e2 in ...
(Or you can write let x, y = e1, e2 in ..., which looks nicer for defining two similar variables to two similar values.)
The following code should at least compile:
let lip list1 =
if list1 = [] then []
else
let list2=List.rev list1 in
let rec lp l1 l2 = match l1,l2 with
| [], [] ->[]
| [], _::_->[]
| h1::_::_, h2::t2 -> (* l1 length >= 2*)
(h1,h2) :: lp(List.tl l1) t2
| h1::_,h2::t2 -> (* l1 length = 1 *)
[]
in
[]
I have made the following changes:
renamed the arguments of lip to make clear they are different from the arguments of lp
removed the alias let l1 = l
changed the if condition to a term of type boolean -- there's not much to compare, so I assume you are checking list1
replaced the list length condition by a pattern match against two heads
the else path is the second match - it might be better to rewrite that one to | [h1, _] -> ...
the definition of lp needs to be followed with the actual body of lip - to make it compile, we just return [] at the moment but you probably would like something else there
As #Jeffrey Scofield already mentioned, you are not using lp in your code. It could help if you added a comment that explains what you'd like to achieve and what the intended role of lp is.

Applying Fold function in F#

let list_min_fold = List.fold (fun acc -> List.min acc ) 0 lst
printfn"Using regular List.fold function:\n The minimum is: %A\n"
(list_min_fold)
When I execute my code this error displays:
error FS0001: The type '('a -> 'b)' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
Why? Please help :(
Are you trying to find the smallest number in a list? If so, you need to use the min function (which takes just two arguments) rather than List.min (which takes a list of arguments):
To keep the code the most similar to your example, you can write (note also that starting with 0 is not going to work, so I used System.Int32.MaxValue instead):
let lst = [4;3;1;2;5;]
let list_min_fold = List.fold (fun acc -> min acc) System.Int32.MaxValue lst
It is also worth noting that the function you pass to fold takes two arguments - the state acc and the current value:
let list_min_fold = List.fold (fun acc v -> min acc v) System.Int32.MaxValue lst
But thanks to partial function application you can omit one of them (as you did), or both of them:
let list_min_fold = List.fold min System.Int32.MaxValue lst
as always Tomas answer is spot on so I have but a small remark:
as you probably saw it makes no sense to try to find the minimum of an empty list (so the function probably should be of type 'a option and when you have an non-empty list it's very easy to use List.reduce (which is basically just a fold for binary operations and min is a great candidate for such an operation):
let list_min xs =
match xs with
| [] -> None
| _ -> List.reduce min xs
|> Some
this way you get:
> list_min [2;1;5;3];;
val it : int option = Some 1
> list_min [2;1;5;3;0];;
val it : int option = Some 0
> list_min ([] : int list);;
val it : int option = None
ok it's a fair point that the question was about fold - so if it has to be exactly List.fold you can of course do (as TheInnerLight remarked):
let list_min xs =
match xs with
| [] -> None
| (x::xs) -> List.fold min x xs
|> Some

Mix values from two List using recursion

I want to mix values using two lists:
List1 : [3; 2; 8; 1; 9; 3; 6]
List2: [5; 7; 0]
Output : [3; 5; 2; 7; 8; 0; 1; 9; 3; 6]
I only found info about list with the same length what about this example when i have diffrent ?
The same length :
let rec mix =function
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
|([],[]) -> []
| _ -> failwith "mix:param";;
mix ([3;2;8;1;9;3;6], [5; 7; 0]) ;;
The best way to break this down is by considering each possible case for a particular step. You currently have:
|(x::xs,y::ys) This is the case where each of the lists has at least one more item left
|([],[]) This is the case where both lists are empty
_ This case handles everything else.
So the cases you are missing are the cases where one list is empty and the other list has at least one item left. Those cases are |(x::xs,[]) and |([],y::ys). So add those two options to your match statement like so:
let rec mix =function
|(x::xs,[]) |([],y::ys) -> failwith "do something here"
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
|([],[]) -> []
| _ -> failwith "mix:param"
You'll notice that you now get a warning indicating that the last case will never be matched so it can be removed like so:
let rec mix =function
|([],[]) -> []
|(x,[]) |([],x) -> failwith "test"
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
Notice how I moved the base case to the top so it gets matched before (x,[]) or ([], x). Now all that is needed is code to handle those last two cases. It looks like this:
|(x,[]) |([],x) -> x i.e. return the rest of the values in the list.
So the final solution looks like this:
let rec mix =function
|([],[]) -> []
|(x,[]) |([],x) -> x
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
A further sneaky optimization you could make would be to remove the base case entirely since it will be covered by the second case. I.e (x,[]) also matches ([],[]) and will return [] as desired. This leaves us with just:
let rec mix =function
|(x,[]) |([],x) -> x
|(x::xs,y::ys) -> x::y::(mix (xs,ys))
Step 1: understand the example
This isn't too hard if you have a good understanding what the example function does. Make sure that you know what the following mean; look them up if you are unsure (search web/Stackoverflow):
Recursion
Basic F# pattern matching
Cons (::), both as an operator to create a list and as a pattern
F# list expressions [...], again both to create lists and as a pattern
If you fully understand the original function, you only need to remove the case(s) you no longer need from the pattern match, and add the new cases: how to finish mixing when reaching the end of one list.
So, I recommend that you solve it yourself before reading the second part of this answer. The MSDN reference for F# is a good place to start. For example, see this page for rules and examples on pattern matching.
Step 2: Solution variant (read Step 1 first!)
Modifying the original function isn't all you can do in this case. Here's a proposal with some improvements:
let rec private mixAux acc = function
| h1 :: t1, h2 :: t2 -> mixAux (h2 :: h1 :: acc) (t1, t2)
| [], t | t, [] -> List.rev acc # t
let mix l1 l2 = mixAux [] (l1, l2)
mix [3; 2; 8; 1; 9; 3; 6] [5; 7; 0] // yields [3; 5; 2; 7; 8; 0; 1; 9; 3; 6]
There are multiple techniques at work here which you might want to look up:
The line beginning with | [], t | t, [] is an or pattern where two cases have only one body. t is matched either one way or the other, but used in the same expression in both cases.
The use of an accumulator, acc, helps to make the function tail recursive. Look up tail recursion if the function needs to work on long inputs or needs to be fast.
The use of private hides the original "auxiliary" function and exposes a function that takes arguments in curried form, and doesn't need the accumulator argument when called.
The code in the question does not follow common formatting conventions. For example, function bodies are usually indented and commas usually followed by a space. See for example this page on formatting conventions for a starting point on how many people format F#.
Well, there are really only four cases, so here is a naive way of doing it:
let rec mx xs ys =
match (xs, ys) with
| (x::xs, y::ys) -> x:: y :: (mx xs ys)
| ([], y::ys) -> y :: (mx [] ys)
| (x::xs, []) -> x :: (mx xs [])
| ([], []) -> []