How to write a composition function in ocaml? [closed] - ocaml

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.

Related

Regular expression to find particular pattern [closed]

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 2 years ago.
Improve this question
I'm a beginner in regex and trying to create regular expression (doing tests using c++/boost::regex_token_iterator) to find particular pattern:
(* some *)(* interesting *) (*test *) (* regular*)(* expressions *) (* and *)
I want to find words, which much exactly to (* xxxx *) pattern, for single case i'm using below expression:
\(\* .+ \*\)
but cannot figure out how to apply it to string similar to above example. I want to get as result:
(* some *)
(* interesting *)
(* expressions *)
Following fragments should not be taken:
(*test *)
(* regular*)
(* and *)
Any help is highly welcomed.
The simplest one:
\(\*\s\w+\s\*\)
You can use
\(\* [^\s()](?:[^()]*[^\s()])? \*\)
See the regex demo
Details
\(\* - a (* string
[^\s()] - any char other than whitespace, ( and )
(?:[^()]*[^\s()])? - an optional occurrence of any zero or more chars other than ( and ) and then any char other than whitespace, ( and )
\*\) - a *) string

Ocaml syntax error : pattern expected in building zip fuction [closed]

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.

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

What is wrong with check_referrer function that i use for CSFR/XSFR protection? [closed]

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 7 years ago.
Improve this question
i have his code in php file and i want to know how that code work. can you please explain this to me by an example (all code)?
if (strpos(preg_replace('/^.+:\/\/(www\.)?/','',$_SERVER['HTTP_REFERER']).'/',preg_replace('/^.+:\/\/(www\.)?/','',$my_base_url))!==0)
what is the meaning of
'/^.+:\/\/(www\.)?/'
in 1st () ?
the all fuction code :
function check_referrer($post_url=false){
global $my_base_url, $my_website_base, $xsfr_first_page, $_GET, $_POST;
if (sizeof($_GET)>0 || sizeof($_POST)>0)
{
if ($_SERVER['HTTP_REFERER'])
{
$base = $my_website_base;
if (!$base) $base = '/';
$_SERVER['HTTP_REFERER'] = sanitize($_SERVER['HTTP_REFERER'],3);
// update checks if HTTP_REFERER and posted url are the same!
if(strpos(urldecode($_SERVER['HTTP_REFERER']),$post_url)!==false) return true;
//if (strpos(preg_replace('/^.+:\/\/(www\.)?/','',$_SERVER['HTTP_REFERER']).'/',preg_replace('/^.+:\/\/(www\.)?/','',$my_base_url).$base)!==0)
if (strpos(preg_replace('/^.+:\/\/(www\.)?/','',$_SERVER['HTTP_REFERER']).'/',preg_replace('/^.+:\/\/(www\.)?/','',$my_base_url))!==0)
{
unset($_SESSION['xsfr']);
$wrongurlrefforme=urldecode($_SERVER['HTTP_REFERER']);
die("");
}
}
elseif ($xsfr_first_page)
{
unset($_SESSION['xsfr']);
die("");
}
}
}
'/^.+:\/\/(www\.)?/' is a regular expression.
It means:
/^ "Starting from the beginning of the string..."
.+ "... match any string that has at least one character"
:\/\/ "... followed by a colon followed by two foward slashes"
(www\.)?/ "... and if there is 'www.' after those, call that "group one""
So ...
preg_replace('/^.+:\/\/(www\.)?/','',$_SERVER['HTTP_REFERER'])
means
"look in the 'HTTP_REFERER' element of the $_SERVER array, and see if it matches the description above. If it does, replace the 'www.' part of it with nothing."
Whatever the result of that is, becomes the first argument to strpos().
The second argument to strpos() is constructed similarly.
Then strpos() tells you where the second string is found in the first. Thus the if statement is asking if the output of strpos() is the same value and type as zero.
A safer comparison would be !=, because you don't care about the types.
That is a regular expression. For example, it will match http://www.

haskell regex substitution

Despite the ridiculously large number of regex matching engines for Haskell, the only one I can find that will substitute is Text.Regex, which, while decent, is missing a few thing I like from pcre. Are there any pcre-based packages which will do substitution, or am I stuck with this?
I don't think "just roll your own" is a reasonable answer to people trying to get actual work done, in an area where every other modern language has a trivial way to do this. Including Scheme. So here's some actual resources; my code is from a project where I was trying to replace "qql foo bar baz qq" with text based on calling a function on the stuff inside the qq "brackets", because reasons.
Best option: pcre-heavy:
let newBody = gsub [re|\s(qq[a-z]+)\s(.*?)\sqq\s|] (unWikiReplacer2 titles) body in do
[snip]
unWikiReplacer2 :: [String] -> String -> [String] -> String
unWikiReplacer2 titles match subList = case length subList > 0 of
True -> " --" ++ subList!!1 ++ "-- "
False -> match
Note that pcre-heavy directly supports function-based replacement, with any
string type. So nice.
Another option: pcre-light with a small function that works but isn't exactly
performant:
let newBody = replaceAllPCRE "\\s(qq[a-z]+)\\s(.*?)\\sqq\\s" (unWikiReplacer titles) body in do
[snip]
unWikiReplacer :: [String] -> (PCRE.MatchResult String) -> String
unWikiReplacer titles mr = case length subList > 0 of
True -> " --" ++ subList!!1 ++ "-- "
False -> PCRE.mrMatch mr
where
subList = PCRE.mrSubList mr
-- A very simple, very dumb "replace all instances of this regex
-- with the results of this function" function. Relies on the
-- MatchResult return type.
--
-- https://github.com/erantapaa/haskell-regexp-examples/blob/master/RegexExamples.hs
-- was very helpful to me in constructing this
--
-- I also used
-- https://github.com/jaspervdj/hakyll/blob/ea7d97498275a23fbda06e168904ee261f29594e/src/Hakyll/Core/Util/String.hs
replaceAllPCRE :: String -- ^ Pattern
-> ((PCRE.MatchResult String) -> String) -- ^ Replacement (called on capture)
-> String -- ^ Source string
-> String -- ^ Result
replaceAllPCRE pattern f source =
if (source PCRE.=~ pattern) == True then
replaceAllPCRE pattern f newStr
else
source
where
mr = (source PCRE.=~ pattern)
newStr = (PCRE.mrBefore mr) ++ (f mr) ++ (PCRE.mrAfter mr)
Someone else's fix: http://0xfe.blogspot.com/2010/09/regex-substitution-in-haskell.html
Another one, this time embedded in a major library: https://github.com/jaspervdj/hakyll/blob/master/src/Hakyll/Core/Util/String.hs
Another package for this purpose: https://hackage.haskell.org/package/pcre-utils
Update 2020
I totally agree with #rlpowell that
I don't think "just roll your own" is a reasonable answer to people trying to get actual work done, in an area where every other modern language has a trivial way to do this.
At the time of this writing, there is also Regex.Applicative.replace for regex substitution, though it's not Perl-compatible.
For pattern-matching and substitution with parsers instead of regex, there is Replace.Megaparsec.streamEdit
The regular expression API in regex-base is generic to the container of characters to match. Doing some kind of splicing generically to implements substitution would be very hard to make efficient. I did not want to provide a crappy generic routine.
Writing a small function to do the substitution exactly how you want is just a better idea, and it can be written to match your container.