Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I want to make fuction called zip so:
zip [1;2;3;4] [5;6;7;8] would produce: [1;5;2;6;3;7;4;8]
but I'm getting an error:
line#4 h2::t2 make error syntax error : pattern expected
What would be the correct syntax?
let rec zip lst1 lst2 =
match lst1 lst2 with
| [] [] -> []
| h1::t1 h2::t2 -> h1 h2::zip t1 t2
|_ _ -> failwith "The lists seems to have different lengths";;
A pattern match can match against only one expression at a time. If you want to match against two lists i.e. two expressions, you will want to combine them into a single expression. The idiomatic way to do this is to pair them up using a tuple, e.g.:
match lst1, lst2 with
| [], [] -> []
| h1::t1, h2::t2 -> (h1, h2)::(zip t1 t2)
| _ -> failwith "Cannot zip lists of different lengths"
The syntax for putting expressions in a tuple technically is (e1, e2, ..., en); but when it is unambiguous e.g. when surrounded by other symbols or keywords that take precedence, OCaml allows leaving out the parentheses and just using the commas.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 12 months ago.
Improve this question
if theta and lambda are two trees/sets, how would I write this function to see if they are the same and if they are the same then the true function will keep them but the false part should remove them and apply lambda to theta.
let compose theta lambda =
match (theta = lambda) with
| true -> (match theta with
| [] -> "{" ^ (format theta) ^ "}" (* "/" ^ (Printf.sprintf "v%d" theta.var) ^ "}" *)
| lambda :: _ -> "{" ^ (format theta) ^ "/" ^ "}" (* (Printf.sprintf "v%d" theta.var) ^ ", " ^ (format lambda.tree) ^ "/" ^ (Printf.sprintf "v%d" lambda.var) ^ "}"*)
)
| false -> ??
;;
You'll need to provide a lot more background if you want help with this problem. You don't give enough details for someone (at least me) to give a helpful answer.
Just one observation: you can't normally use the polymorphic equality operator = to compare two trees that represent sets. Depending on the design of your trees, there are usually many representations for the same set. The polymorphic equality operator will treat all the different representations as being different. In other words, you need to write a domain-specific equality comparison yourself. If you use the OCaml Set module, you can use S.equal.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
The definition
firsts :: RE sym -> [sym]
firsts = undefined
The RE data
data RE sym -- sym is type of alphabet symbols
= RSym sym -- match single symbol
| REps -- match empty string
| RZero -- match nothing
| RStar (RE sym) -- choice
| RPlus (RE sym) -- concatenation
| RAlt (RE sym) (RE sym) -- 0+ repetition
| RSeq (RE sym) (RE sym) -- 1+ repetition
deriving (Show)
The Alphabet used in regex
data Alphabet = A | B | C deriving (Show, Eq)
firsts re returns a list containing every symbol that occurs first in some string in the language for re.
For example, if re represents "A(C|B)|BC", then the strings in its language are AB, AC, and BC. In this case, firsts re might return [A,B].
Note that the type signature does not include Eq sym or Ord sym. This means that your code will be unable to sort or remove duplicates from the list of symbols it returns.
The requirements your code must satisfy are:
the list returned must be finite (even if the language is infinite!)
every symbol in the list must be the first symbol in some string in the language
for every string in the language, its first symbol must occur in the list
Individual symbols may occur in any order, and may be duplicated any finite number of
times.
The idea is to analyze the regular expression, not produce all possible strings for that regular expression. For example the RSym sym clearly has sym as first (and only) character whereas REps has no start characters.
It thus means that you should define a function that aims to find the initial characters. You thus implement such function like:
firsts :: RE sym -> [sym]
firsts (RSym sym) = [sym]
firsts REps = []
firsts RZero = …
firsts (RStar sub) = …
firsts (RPlus sub) = …
firsts (RAlt sub1 sub2) = …
firsts (RSeq sub1 sub2) = …
where sub and sub1 and sub2 are sub-regexes. You will thus for some of these regular expressions have to make recursive calls to find out the first characters of the subregex(es).
For (RSeq sub1 sub2) you will need to make a helper function matchEmpty :: RE sym -> Bool that checks if the regular expression matches with the empty string. If that is the case then the first characters of sub2 can be the first characters of the regex whereas if sub1 does not match with the empty string, then that is impossible.
I have just started to learn ocaml and I find it difficult to extract small list of chars from a bigger list of chars.
lets say I have:
let list_of_chars = ['#' ; 'a' ; 'b' ; 'c'; ... ; '!' ; '3' ; '4' ; '5' ];;
I have the following knowledge - I know that in the
list above I have '#' followed by a '!' in some location further in the list .
I want to extract the lists ['a' ;'b' ;'c' ; ...] and ['3' ; '4' ; '5'] and do something with them,
so I do the following thing:
let variable = match list_of_chars with
| '#'::l1#['!']#l2 -> (*[code to do something with l1 and l2]*)
| _ -> raise Exception ;;
This code doesn't work for me, it's throwing errors. Is there a simple way of doing this?
(specifically for using match)
As another answer points out, you can’t use pattern matching for this because pattern matching only lets you use constructors and # is not a constructor.
Here is how you might solve your problem
let split ~equal ~on list =
let rec go acc = function
| [] -> None
| x::xs -> if equal x on then Some (rev acc, xs) else go (x::acc) xs
in
go [] list
let variable = match list_of_chars with
| '#'::rest ->
match split rest ~on:'!' ~equal:(Char.equal) with
| None -> raise Exception
| Some (left,right) ->
... (* your code here *)
I’m now going to hypothesise that you are trying to do some kind of parsing or lexing. I recommend that you do not do it with a list of chars. Indeed I think there is almost never a reason to have a list of chars in ocaml: a string is better for a string (a chat list has an overhead of 23x in memory usage) and while one might use chars as a kind of mnemonic enum in C, ocaml has actual enums (aka variant types or sum types) so those should usually be used instead. I guess you might end up with a chat list if you are doing something with a trie.
If you are interested in parsing or lexing, you may want to look into:
Ocamllex and ocamlyacc
Sedlex
Angstrom or another parser generator like it
One of the regular expression libraries (eg Re, Re2, Pcre (note Re and Re2 are mostly unrelated)
Using strings and functions like lsplit2
# is an operator, not a valid pattern. Patterns need to be static and can't match a varying number of elements in the middle of a list. But since you know the position of ! it doesn't need to be dynamic. You can accomplish it just using :::
let variable = match list_of_chars with
| '#'::a::b::c::'!'::l2 -> let l1 = [a;b;c] in ...
| _ -> raise Exception ;;
This question already has answers here:
What does the "#" symbol mean in reference to lists in Haskell?
(4 answers)
Closed 9 years ago.
I am beginner in Haskell. I was doing simple excersice in Haskell which is to write compress function, since my code of this function was pretty long and not really what i wanted to do i checked the solution, and i found this one:
compress (x:ys#(y:_))
| x == y = compress ys
| otherwise = x : compress ys
compress ys = ys
The problem for me is the '#' which i don't really know what is doing, is there anyone out there willing to explain me how this works?
# is used to bind a name to the value of the whole pattern match. Think of it like this
foo fullList#(x:xs) = ...
Is like saying
foo (x:xs) = ...
where fullList = x:xs
or, if you like
foo fullList = case fullList of
(x:xs) -> ...
So in your case
ys is equal to the tail of the original list, and the head of ys is y.
It's worth reading a good haskell tutorial to pick up some of this syntax.
# is used to pattern match a value while still keeping a reference to the whole value. An example is
data Blah = Blah Int Int
f :: Blah -> String
f val#(Blah x y) = -- some expression
f (Blah 1 2)
In the last call, val would be Blah 1 2, x would be 1 and y would be 2.
I recommend you read the relevant section of Learn you a Haskell for a Great Good!
From the link:
There's also a thing called as patterns. Those are a handy way of
breaking something up according to a pattern and binding it to names
whilst still keeping a reference to the whole thing. You do that by
putting a name and an # in front of a pattern. For instance, the
pattern xs#(x:y:ys). This pattern will match exactly the same thing as
x:y:ys but you can easily get the whole list via xs instead of
repeating yourself by typing out x:y:ys in the function body again.
I found this useful article on using Active Patterns with Regular Expressions:
http://www.markhneedham.com/blog/2009/05/10/f-regular-expressionsactive-patterns/
The original code snippet used in the article was this:
open System.Text.RegularExpressions
let (|Match|_|) pattern input =
let m = Regex.Match(input, pattern) in
if m.Success then Some (List.tl [ for g in m.Groups -> g.Value ]) else None
let ContainsUrl value =
match value with
| Match "(http:\/\/\S+)" result -> Some(result.Head)
| _ -> None
Which would let you know if at least one url was found and what that url was (if I understood the snippet correctly)
Then in the comment section Joel suggested this modification:
Alternative, since a given group may
or may not be a successful match:
List.tail [ for g in m.Groups -> if g.Success then Some g.Value else None ]
Or maybe you give labels to your
groups and you want to access them by
name:
(re.GetGroupNames()
|> Seq.map (fun n -> (n, m.Groups.[n]))
|> Seq.filter (fun (n, g) -> g.Success)
|> Seq.map (fun (n, g) -> (n, g.Value))
|> Map.ofSeq)
After trying to combine all of this I came up with the following code:
let testString = "http://www.bob.com http://www.b.com http://www.bob.com http://www.bill.com"
let (|Match|_|) pattern input =
let re = new Regex(pattern)
let m = re.Match(input) in
if m.Success then Some ((re.GetGroupNames()
|> Seq.map (fun n -> (n, m.Groups.[n]))
|> Seq.filter (fun (n, g) -> g.Success)
|> Seq.map (fun (n, g) -> (n, g.Value))
|> Map.ofSeq)) else None
let GroupMatches stringToSearch =
match stringToSearch with
| Match "(http:\/\/\S+)" result -> printfn "%A" result
| _ -> ()
GroupMatches testString;;
When I run my code in an interactive session this is what is output:
map [("0", "http://www.bob.com"); ("1", "http://www.bob.com")]
The result I am trying to achieve would look something like this:
map [("http://www.bob.com", 2); ("http://www.b.com", 1); ("http://www.bill.com", 1);]
Basically a mapping of each unique match found followed by the count of the number of times that specific matching string was found in the text.
If you think I'm going down the wrong path here please feel free to suggest a completely different approach. I'm somewhat new to both Active Patterns and Regular Expressions so I have no idea where to even begin in trying to fix this.
I also came up with this which is basically what I would do in C# translated to F#.
let testString = "http://www.bob.com http://www.b.com http://www.bob.com http://www.bill.com"
let matches =
let matchDictionary = new Dictionary<string,int>()
for mtch in (Regex.Matches(testString, "(http:\/\/\S+)")) do
for m in mtch.Captures do
if(matchDictionary.ContainsKey(m.Value)) then
matchDictionary.Item(m.Value) <- matchDictionary.Item(m.Value) + 1
else
matchDictionary.Add(m.Value, 1)
matchDictionary
Which returns this when run:
val matches : Dictionary = dict [("http://www.bob.com", 2); ("http://www.b.com", 1); ("http://www.bill.com", 1)]
This is basically the result I am looking for, but I'm trying to learn the functional way to do this, and I think that should include active patterns. Feel free to try to "functionalize" this if it makes more sense than my first attempt.
Thanks in advance,
Bob
Interesting stuff, I think everything you are exploring here is valid. (Partial) active patterns for regular expression matching work very well indeed. Especially when you have a string which you want to match against multiple alternative cases. The only thing I'd suggest with the more complex regex active patterns is that you give them more descriptive names, possibly building up a collection of different regex active patterns with differing purposes.
As for your C# to F# example, you can have functional solution just fine without active patterns, e.g.
let testString = "http://www.bob.com http://www.b.com http://www.bob.com http://www.bill.com"
let matches input =
Regex.Matches(input, "(http:\/\/\S+)")
|> Seq.cast<Match>
|> Seq.groupBy (fun m -> m.Value)
|> Seq.map (fun (value, groups) -> value, (groups |> Seq.length))
//FSI output:
> matches testString;;
val it : seq<string * int> =
seq
[("http://www.bob.com", 2); ("http://www.b.com", 1);
("http://www.bill.com", 1)]
Update
The reason why this particular example works fine without active patterns is because 1) you are only testing one pattern, 2) you are dynamically processing the matches.
For a real world example of active patterns, let's consider a case where 1) we are testing multiple regexes, 2) we are testing for one regex match with multiple groups. For these scenarios, I use the following two active patterns, which are a bit more general than the first Match active pattern you showed (I do not discard first group in the match, and I return a list of the Group objects, not just their values -- one uses the compiled regex option for static regex patterns, one uses the interpreted regex option for dynamic regex patterns). Because the .NET regex API is so feature filled, what you return from your active pattern is really up to what you find useful. But returning a list of something is good, because then you can pattern match on that list.
let (|InterpretedMatch|_|) pattern input =
if input = null then None
else
let m = Regex.Match(input, pattern)
if m.Success then Some [for x in m.Groups -> x]
else None
///Match the pattern using a cached compiled Regex
let (|CompiledMatch|_|) pattern input =
if input = null then None
else
let m = Regex.Match(input, pattern, RegexOptions.Compiled)
if m.Success then Some [for x in m.Groups -> x]
else None
Notice also how these active patterns consider null a non-match, instead of throwing an exception.
OK, so let's say we want to parse names. We have the following requirements:
Must have first and last name
May have middle name
First, optional middle, and last name are separated by a single blank space in that order
Each part of the name may consist of any combination of at least one or more letters or numbers
Input may be malformed
First we'll define the following record:
type Name = {First:string; Middle:option<string>; Last:string}
Then we can use our regex active pattern quite effectively in a function for parsing a name:
let parseName name =
match name with
| CompiledMatch #"^(\w+) (\w+) (\w+)$" [_; first; middle; last] ->
Some({First=first.Value; Middle=Some(middle.Value); Last=last.Value})
| CompiledMatch #"^(\w+) (\w+)$" [_; first; last] ->
Some({First=first.Value; Middle=None; Last=last.Value})
| _ ->
None
Notice one of the key advantages we gain here, which is the case with pattern matching in general, is that we are able to simultaneously test that an input matches the regex pattern, and decompose the returned list of groups if it does.