Two action after then in Ocaml - ocaml

Is it possible to make two actions after a then in Ocaml ?
I try to search and I found that I could use a semicolon.
Should I use it like this ? :
let test (a:int)=
if a = 0
then print_int(1);print_int(2)
else()
;;
It's just an example. In my case I want to launch a function and give a tuple like that :
let move_square(x,y:int*int):int*int=
..
let direction : int = Random.int(5);
if direction = 0
then draw_square(x,y+1);x,y+1
else ..
Thanks for helping me

You can refer to §Séquence of https://caml.inria.fr/pub/old_caml_site/FAQ/qrg-fra.html.
Generally you have to group ocaml statement in an if-then-else structure,
either by using explicitly beginand end keywords, or by using parenthesis to group your sequence.

Related

How to simplify this google sheets regex sequence?

I want to make the following transformation to a set of datas in my google spreadsheets :
6 views -> 6
73K views -> 73000
3650 -> 3650
163K views -> 163000
1.2K views -> 1200
52.5K -> 52500
All the datas are in a column and depending on the case I need to apply a specific transformation.
I tried to put all the regex in one formula but I failed. I always had a case over two regular expressions etc.
Anyaway I end up making these regex one case by one case in different columns. It works fine but I feel like it could slowdown the sheet since I except a lot of data coming into this sheet.
Here is the sheet : spreadsheet
Thank you for your help !
Use regexreplace(), like this:
=arrayformula(
iferror( 1 /
value(
regexreplace(
regexreplace(trim(A2:A), "\s*K", "e3"),
" views", ""
)
)
^ -1 )
)
See your sample spreadsheet.
replace 'views' using regex: /(?<=(\d*\.?\d+\K?)) views/gi
To replace 'K' with or without decimal value, first, detect K then replace K with an empty string and multiply by 1000.
use call back function as:
txt.replace(/(?<=(\d*\.?\d+\K?)) views/gi, '').replace(/(?<=\d)\.?\d+K/g, x => x.replace(/K/gi, '')*1000)
code:
arr = [`6 views`,
`73K views`,
`3650`,
`163K views`,
`1.2K views`,
`52.5K`];
arr.forEach(txt => {
console.log(txt.replace(/(?<=(\d*\.?\d+\K?)) views/gi, '').replace(/(?<=\d)\.?\d+K/g, x => x.replace(/K/gi, '')*1000))
})
Output:
6
73000
3650
163000
1200
52500
Say your inputs are in column A. Empty cells allowed. In any other column,
=arrayformula(if(A2:A<>"",value(substitute(substitute(A2:A," views",""),"K","e3")),))
works.
Adjust the range A2:A as needed.
Also note that non-empty cells with empty strings are ignored.
Basically, since Google Sheet's regex engine doesn't support look around, it is more efficient to take advantage of the rather strict patterns in your application and use substitute() instead.

What is the idiomatic (and fast) way of treating the empty list/Seq as failure in a short-circuiting operation?

I have a situation where I am using functions to model rule applications, with each function returning the actions it would take when applied, or, if the rule cannot be applied, the empty list. I have a number of rules that I would like to try in sequence and short-circuit. In other languages I am used to, I would treat the empty sequence as false/None and chain them with orElse, like this:
def ruleOne(): Seq[Action] = ???
def ruleTwo(): Seq[Action] = ???
def ruleThree(): Seq[Action] = ???
def applyRules(): Seq[Action] = ruleOne().orElse(ruleTwo).orElse(ruleThree)
However, as I understand the situation, this will not work and will, in fact, do something other than what I expect.
I could use return which feels bad to me, or, even worse, nested if statements. if let would have been great here, but AFAICT Scala does not have that.
What is the idiomatic approach here?
You have different approaches here.
One of them is combining all the actions inside a Seq (so creating a Seq[Seq[Action]]) and then using find (it will return the first element that matches a given condition). So, for instance:
Seq(ruleOne, ruleTwo, ruleThree).find(_.nonEmpty).getOrElse(Seq.empty[Action])
I do not know clearly your domain application, but the last getOrElse allows to convert the Option produced by the find method in a Seq. This method though eval all the sequences (no short circuit).
Another approach consists in enriching Seq with a method that simulated your idea of orElse using pimp my library/extensions method:
implicit class RichSeq[T](left: Seq[T]) {
def or(right: => Seq[T]): Seq[T] = if(left.isEmpty) { right } else { left }
}
The by name parameter enable short circuit evaluation. Indeed, the right sequence is computed only if the left sequence is empty.
Scala 3 has a better syntax to this kind of abstraction:
extension[T](left: Seq[T]){
def or(rigth: => Seq[T]): Seq[T] = if(left.nonEmpty) { left } else { rigth }
}
In this way, you can call:
ruleOne or ruleTwo or ruleThree
Scastie for scala 2
Scastie for scala 3

cts:value-match on xs:dateTime() type in Marklogic

I have a variable $yearMonth := "2015-02"
I have to search this date on an element Date as xs:dateTime.
I want to use regex expression to find all files/documents having this date "2015-02-??"
I have path-range-index enabled on ModifiedInfo/Date
I am using following code but getting Invalid cast error
let $result := cts:value-match(cts:path-reference("ModifiedInfo/Date"), xs:dateTime("2015-02-??T??:??:??.????"))
I have also used following code and getting same error
let $result := cts:value-match(cts:path-reference("ModifiedInfo/Date"), xs:dateTime(xs:date("2015-02-??"),xs:time("??:??:??.????")))
Kindly help :)
It seems you are trying to use wild card search on Path Range index which has data type xs:dateTime().
But, currently MarkLogic don't support this functionality. There are multiple ways to handle this scenario:
You may create Field index.
You may change it to string index which supports wildcard search.
You may run this workaround to support your existing system:
for $x in cts:values(cts:path-reference("ModifiedInfo/Date"))
return if(starts-with(xs:string($x), '2015-02')) then $x else ()
This query will fetch out values from lexicon and then you may filter your desired date.
You can solve this by combining a couple cts:element-range-querys inside of an and-query:
let $target := "2015-02"
let $low := xs:date($target || "-01")
let $high := $low + xs:yearMonthDuration("P1M")
return
cts:search(
fn:doc(),
cts:and-query((
cts:element-range-query("country", ">=", $low),
cts:element-range-query("country", "<", $high)
))
)
From the cts:element-range-query documentation:
If you want to constrain on a range of values, you can combine multiple cts:element-range-query constructors together with cts:and-query or any of the other composable cts:query constructors, as in the last part of the example below.
You could also consider doing a cts:values with a cts:query param that searches for values between for instance 2015-02-01 and 2015-03-01. Mind though, if multiple dates occur within one document, you will need to post filter manually after all (like in option 3 of Navin), but it could potentially speed up post-filtering a lot..
HTH!

R inverted regex pattern for ls

In R I load one environment from a file that contains various timeseries plus one configuration object/vector.
I want to process all timeseries in the environment in a loop but want to exclude the configuration object.
At the moment my code is like this:
for(x in ls(myEnv)) {
if(x!="configData") {
# do something, e. g.
View(myEnv[[x]], x)
}
}
Is there a way to use the pattern parameter of the ls-function to omit the if clause?
for(x in ls(myEnv, pattern="magic regex picks all but *configData*")) {
# do something, e. g.
View(myEnv[[x]], x)
}
All examples I could find for pattern were based on a whitelist-approach (positive list), but I'd like to get all except configData.
Is this possible?
Thanks.
for( x in setdiff(ls(myEnv), "configData") )
and
for(x in grep("configData", ls(myEnv), value=TRUE, invert=TRUE))
both work fine, thanks.
BTW, cool! I wasn't aware of hiding it by using a leading "." ... so the best solution for me is to make sure that configData becomes .configData in the source file so that ls() won't show it.

Ocaml Error: Unbound record field label length

This is the error I'm getting and I have no idea why: "Error: Unbound record field label length "
Does anyonw know?
let rastavi str =
let sublist = ref [] in
let list = ref [] in
for i = ((str.length str)1) [down]to 0 do
if str.[i] =' ' then (str.[i] :: !sublist)
else (list := (!sublist:: !list)) sublist = []
done ;;
You're using OO notation to get the length of a string. OCaml uses functional notation. So it looks like this:
String.length str
Not like this:
str.length (* OO notation, not in OCaml *)
Edit:
Side comment: this solution is very much an imperative take on the problem. If you're trying to learn the FP mindset, you should try to think recursively and immutably. Since this looks like homework, it's very likely a functional solution is what you want.
But here are a few other problems in your original code:
You have two expressions next to each other with nothing in between. If you want to "do" two things, you need to separate them with a semicolon ; (however, this is imperative style)
You're using = which compares two values for equality. If you want to assign a value to a reference you need to use :=. (Imperative style, again.)