Short-hand OCaml "type equality" - ocaml

Is there a short-hand OCaml notation for a function that could be implemented like this:
match e with
Mycons ( _ ) -> true
| _ -> false
I was thinking along the lines of typeof(e) == Mycons but i didn't find anything yet.

I've often wanted something like this, though "type equality" is not a good name for it (IMHO). Mycons is a value constructor; it represents a value not a type. For nullary constructors you can use something like ((=) None), but other than this I haven't found a more concise way to write it.

There is a shorter notation:
let isMycons a = function | Mycons(_) -> true | _ -> false
Is a one liner and as elegant as a match.

Related

Substituting an operation in Z3 expression

I have a Z3 formula of the form (> Expr1 Expr2), and I would like to change it by (< Expr1 Expr2), while preserving the structure of Expr1 and Expr2. As I understand, substitute is helpful to replace variables by others; but I am not sure on which arguments I should give to change the operator, if that is even possible. Is it possible with substitute or by another method?
I am using the OCaml bindings.
Thanks in advance for your answers :)
You can just create a new expression, e.g.,
let ult_of_ugt ctxt exp = match Expr.get_args exp with
| [x; y] -> BitVector.mk_ult ctxt x y
| _ -> invalid_arg "expected two operands"

(Ocaml) Using 'match' to extract list of chars from a list of chars

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 ;;

Pattern matching on string

say i have the following type definition:
type e = AES | DES | SALSA20
Then, i have a function which has an argument of type string, this argument could be "AES", "DES", "SALSA20", or something else. How could I first turn this string into a type and then match this type with possible types? Or, is it necessary because one may argue you can just match a string directly as the following?
match str with
| "AES" -> do something...
| "DES" -> do something else...
If possible, can I also get a basic intro to how pattern-matching works on string? I feel direct string matching will be much slower...
You can write a function like this:
let e_of_string = function
| "AES" -> AES
| "DES" -> DES
| "SALSA20" -> SALSA20
| _ -> raise (Invalid_argument "e_of_string")
I examined the native code generated by OCaml 4.01.0; it compares the supplied string against each of the given strings in order. If there are a lot of strings to check, this is, as you say, pretty slow.
To get more powerful string matching, you could use regular expressions from the Str module, or you could use ocamllex.
You can do it either way. If you are going to perform multiple matches then mapping the string to a data type first makes a lot of sense. For just a single match, I would pick whichever leads to the most straightforward code (or the most consistent, if this is something that is done elsewhere in your code base).
Mapping to a type might look something like:
type thing = AES | DES | SALSA20
let thing_of_string = function
| "AES" -> AES
| "DES" -> DES
| "SALSA20" -> SALSA20
| _ -> failwith "not a thing"
String matching was improved recently and should be acceptably efficient for what it is. I would still avoid performing the same string match many times.

The '#' sign in Haskell [duplicate]

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.

Ocaml Pattern Matching

I am pretty new to OCaml and pattern matching, so I was having a hard time trying to figure this out.
Say that I have a list of tuples. What I want to do is match a parameter with one of the tuples based on the first element in the tuple, and upon doing so, I want to return the second element of the tuple. So for example, I want to do something like this:
let list = [ "a", 1; "b", 2; "c", 3; "d", 4 ] ;;
let map_left_to_right e rules = match e with
| first -> second
| first -> second
| first -> second
If I use map_left_to_right "b" list, I want to get 2 in return.
I therefore want to list out all first elements in the list of rules and match the parameter with one of these elements, but I am not sure how to do so. I was thinking that I need to use either List.iter or List.for_all to do something like this. Any help would be appreciated. Thanks!
Pattern matching is intended for cases where you want to match a fixed list of patterns. In your current situation, the idiomatic thing to use is List.assoc:
let map_left_to_right e rules default =
try List.assoc e rules with Not_found -> default
You need to provide a default when the element is not found. Here, map_left_to_right "b" list 0 would return 2 as expected, and map_left_to_right "z" list 0 would return 0.
Match only matches against fixed patterns, not variables. An appropriate use of matching in this case would look like this: (note the inclusion of a "default" just as in the other answer)
let list = [ "a", 1; "b", 2; "c", 3; "d", 4 ]
let rec map_left_to_right e rules default = match rules with
[] -> default (* No rules left to match *)
| (first,second)::rest -> (* At least one rule remaining, which we'll put into first,second *)
if first = e
then second
else map_left_to_right e rest default
If we want to return 0 if nothing is found, then this would be called like so:
map_left_to_right "b" list 0
All of this is functionally equivalent to the code in the other answer, and in practice I would recommend using that code since it's smaller and makes better use of existing libraries, but I thought that I would give this code because it better illustrates how pattern matching would actually be applied in this case.