mudrz
September 17, 2020, 4:05pm
1
I should clarify that I’m using JaneStreet’s Base and I want to use bit operations on Int64 numbers
Int64
defines a lsl
infix operator:
val ( lsl ) : int64 -> int -> int64
and I want to describe some operation:
((1L lsl 2) - 1L) lsl (10 - 1)
this leads to bigger issues than anticipated:
lsl
is moving an int64
number with int
bits
-> so I need to perform additions and subtractions and etc. on both int64
and int
initially I thought - I’ll just open Int64 since that’s what I need:
let do_things =
let open Int64 in
((1L lsl 2) - 1L) lsl (10 - 1)
but -
now works on int64
, not int
-> 10 - 1
doesn’t work
I tried defining an infix operator, so that I don’t need to open the whole Int64
module:
let ( lsl ) = Int64.shift_left
let do_things =
((1L lsl 2) - 1L) lsl (10 - 1)
but this doesn’t work either since - 1L
now expects ints
the closest approximation to what I would fine useful has been:
let do_things =
let shift = (10 - 1) in
let open Int64 in
((1L lsl 2) - 1L) lsl shift
but it is fairly annoying to keep track of which syntax is overriden when;
How do people mix numeric operations of different types? is there a better way?
this is not very ergonomic
bcc32
September 17, 2020, 4:14pm
2
One way to handle this is to decide which operators you’re going to be using unqualified (only pick one module), and then do local opens for the rest. For example, if you pick Int64
to be primary:
let do_things =
let open Int64.O in
((1L lsl 2) - 1L) lsl Int.(10 - 1)
(In Base, Int.O
and similar modules expose just the operators, abs
, neg
, and zero
in that module)
In more extreme cases, you might end up just using the operators as ordinary functions:
let do_things =
Int64.shift_left (Int64.(-) (Int64.shift_left 1L 2) 1L) (10 - 1)
This is probably more appropriate if there’s just a couple of, say, int64 operations among a vast majority of int operations.
1 Like
mudrz
September 17, 2020, 4:46pm
3
Thanks @bcc32 I was not aware that you can open a module for a single operation, this is already much better;
I was hoping to get to something close to:
let do_things = ((1L <<< 2) - 1L) <<< (10 - 1)
but I guess in OCaml it’s not possible to have -
infer int
or int64
depending on the number?
CraigFe
September 17, 2020, 6:38pm
4
Indeed, it is not. OCaml has no ad-hoc polymorphism (yet …)
1 Like
bcc32
September 17, 2020, 7:48pm
5
It’s a little ugly, but you could do something similar to what is done for the floating-point operators:
let (+%) = Base.Int64.(+)
let (-%) = Base.Int64.(-)
...
That would let you intermix the two operators because they would be distinguished by the extra character. Of course, you could choose something other than %
: https://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
mudrz
September 18, 2020, 8:08am
6
thanks, got it, at least now it is more readable and looking forward to ad hoc polymorphism