Static casting between types for Generic nested records - casting

Nested F# Record with generic type parameter, how do I statically cast between types in nested structure equivalent to traversing and performing 'T |> 'K, e.g. float |> int?
Currently I am Naively traversing the nested records and explicitly converting the type with from:float |> to:int or equivalently int(from). However, this is not very beautiful.
type Person<'T> = {Id : int; Value : 'T}
type Family<'T> = {Id : 'T; People : seq<Person<'T>>}
let fam1 = {Id = 1.0; People = [{Id = 1.1; Value = 2.9}; {Id = 1.2; Value = 4.4}]} : Family<float>
let fam2 = {Id = 2.0; People = [{Id = 2.1; Value = 3.9}; {Id = 2.2; Value = 5.4}]} : Family<float>
let partyFloat = seq{ yield fam1; yield fam2}
// In general, how to do this from a type T to a type K where conversion using T |> K will work
let partyInt : seq<Family<int>> = partyFloat
How to statically and/or
lazily convert to seq<Family<int>>?
In my real world case I have a DiffSharp D type that can be converted to a float with D |> float or float(D).

There is no magic way to cast the insides of types, you have to write your own.
It is idiomatic for F# and functional programming in general (and I personally recommend it, too) to write small functions for simple data transformations, and then assemble them together:
let mapPerson f p = { Id = p.Id; Value = f p.Value }
let mapFamily f fm = { Id = f fm.Id; People = Seq.map (mapPerson f) fm.People }
let mapParty f = Seq.map (mapFamily f)
let partyInt = mapParty int partyFloat
But of course you can do it in one big messy go:
let partyInt =
partyFloat
|> Seq.map (fun fm ->
{ Id = int fm.Id
People =
fm.People
|> Seq.map (fun p ->
{ Id = p.Id; Value = int p.Value }
)
}
)

It seems like what you are asking for are covariance ie that this should compile
let vs : obj list = ["1"; "2"]
F# doesn't support covariance (or contravariance) and probably never will. C# does however so you could write something like this
using System.Collections.Generic;
interface IPerson<out T>
{
int Id { get; }
T Value { get; }
}
interface IFamily<out T>
{
int Id { get; }
IEnumerable<IPerson<T>> Members { get; }
}
static class Program
{
static IFamily<string> CreateFamily()
{
return null;
}
static void Main(string[] args)
{
IFamily<string> familyOfString = CreateFamily();
IFamily<object> familyOfObject = familyOfString;
}
}
However, there's a functional pattern that could help us called polymorphic lenses.
(Picture from reddit thread: https://www.reddit.com/r/haskell/comments/2qjnho/learning_curves_for_different_programming/)
I used to think that polymorphic lenses isn't possible in F# due to the lack of higher-rank types. However, there's a hidden gem out there: http://www.fssnip.net/7Pk
Vesa Karvonen (IIRC he is also behind hopac so he's pretty cool) implements polymorphic lenses in F# using some pretty interesting tricks.
We can then map the inner values of an immutable structure reasonably easy.
let input : Family<int> =
{
Id = 1
Members = [{ Id = 10; Value = 123}; { Id = 11; Value = 456}]
}
printfn "%A" input
let output : Family<string> =
input
|> over Family.membersL (overAll Person.valueL ((+) 1 >> string))
printfn "%A" output
Full source code
// ----------------------------------------------------------------------------
// The code below taken from: http://www.fssnip.net/7Pk
// by Vesa+Karvonen - http://www.fssnip.net/authors/Vesa+Karvonen
// ----------------------------------------------------------------------------
type LensFunctor<'a> =
| Over of 'a
| View
member t.map a2b =
match t with
| Over a -> Over (a2b a)
| View -> View
type Lens<'s,'t,'a,'b> = ('a -> LensFunctor<'b>) -> 's -> LensFunctor<'t>
module Lens =
let view l s =
let r = ref Unchecked.defaultof<_>
s |> l (fun a -> r := a; View) |> ignore
!r
let over l f =
l (f >> Over) >> function Over t -> t | _ -> failwith "Impossible"
let set l b = over l <| fun _ -> b
let (>->) a b = a << b
let lens get set = fun f s ->
(get s |> f : LensFunctor<_>).map (fun f -> set f s)
let fstL f = lens fst (fun x (_, y) -> (x, y)) f
let sndL f = lens snd (fun y (x, _) -> (x, y)) f
// ----------------------------------------------------------------------------
// The code above taken from: http://www.fssnip.net/7Pk
// by Vesa+Karvonen - http://www.fssnip.net/authors/Vesa+Karvonen
// ----------------------------------------------------------------------------
let overAll l f = List.map (over l f)
open Lens
type Person<'T> = { Id : int; Value : 'T }
module Person =
let idS i p = { p with Id = i }
let valueS v { Id = i } = { Id = i; Value = v }
let idL f = lens (fun {Id = i } -> i) idS f
let valueL f = lens (fun {Value = v } -> v) valueS f
type Family<'T> = { Id : int; Members : Person<'T> list }
module Family =
let idS i f = { f with Id = i }
let membersS m { Id = i } = { Id = i; Members = m }
let idL f = lens (fun {Id = i } -> i) idS f
let membersL f = lens (fun {Members = m } -> m) membersS f
[<EntryPoint>]
let main argv =
let input =
{
Id = 1
Members = [{ Id = 10; Value = 123}; { Id = 11; Value = 456}]
}
printfn "%A" input
let output =
input
|> over Family.membersL (overAll Person.valueL ((+) 1 >> string))
printfn "%A" output
0

Related

Evaluation order of let-in expressions with tuples

My old notes on ML say that
let (๐‘ฃโ‚, โ€ฆ , ๐‘ฃโ‚™) = (๐‘กโ‚, โ€ฆ , ๐‘กโ‚™) in ๐‘กโ€ฒ
is a syntactic sugar for
(ฮป ๐‘ฃโ‚™. โ€ฆ (ฮป ๐‘ฃโ‚. ๐‘กโ€ฒ)๐‘กโ‚ โ€ฆ )๐‘กโ‚™
and that
let (๐‘ฃโ‚, ๐‘ฃโ‚‚) = ๐‘ก ๐‘กโ€ฒ in ๐‘กโ€ณ
is equivalent to
let ๐‘ฃ = ๐‘ก ๐‘กโ€ฒ in
let ๐‘ฃโ‚‚ = snd ๐‘ฃ in
let ๐‘ฃโ‚ = fst ๐‘ฃ in
๐‘กโ€ณ
where
each ๐‘ฃ (with or without a subscript) stands for a variable,
each ๐‘ก (with or without a sub- or a superscript) stands for a term, and
fst and snd deliver the first and second component of a pair, respectively.
I'm wondering whether I got the evaluation order right because I didn't note the original reference. Could anyone ((confirm or reject) and (supply a reference))?
It shouldn't matter whether it's:
let ๐‘ฃ = ๐‘ก ๐‘กโ€ฒ in
let ๐‘ฃโ‚‚ = snd ๐‘ฃ in
let ๐‘ฃโ‚ = fst ๐‘ฃ in
๐‘กโ€ณ
Or:
let ๐‘ฃ = ๐‘ก ๐‘กโ€ฒ in
let ๐‘ฃโ‚ = fst ๐‘ฃ in
let ๐‘ฃโ‚‚ = snd ๐‘ฃ in
๐‘กโ€ณ
Since neither fst nor snd have any side-effects. Side-effects may exist in the evaluation of ๐‘ก ๐‘กโ€ฒ but that's done before the let binding takes place.
Additionally, as in:
let (๐‘ฃโ‚, ๐‘ฃโ‚‚) = ๐‘ก ๐‘กโ€ฒ in ๐‘กโ€ณ
Neither ๐‘ฃโ‚ nor ๐‘ฃโ‚‚ is reliant on the value bound to the other to determine its value, so the order in which they're bound is again seemingly irrelevant.
All of that said, there may be an authoritative answer from those with deeper knowledge of the SML standard or the inner workings of OCaml's implementation. I simply am uncertain of how knowing it will provide any practical benefit.
Practical test
As a practical test, running some code where we bind a tuple of multiple expressions with side-effects to observe order of evaluation. In OCaml (5.0.0) the order of evaluation is observed to be right-to-left. We observe tthe same when it comes to evaluating the contents of a list where those expressions have side-effects as well.
# let f () = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let (a, b, c) = (f (), g (), h ()) in a + b + c;;
h
g
f
- : int = 6
# let f () = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let (c, b, a) = (h (), g(), f ()) in a + b + c;;
f
g
h
- : int = 6
# let f _ = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let a () = print_endline "a" in
let b () = print_endline "b" in
let (c, d, e) = (f [a (); b ()], g (), h ()) in
c + d + e;;
h
g
b
a
f
- : int = 6
In SML (SML/NJ v110.99.3) we observe the opposite: left-to-right evaluation of expressions.
- let
= fun f() = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= val (a, b, c) = (f(), g(), h())
= in
= a + b + c
= end;
f
g
h
val it = 6 : int
- let
= fun f() = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= val (c, b, a) = (h(), g(), f())
= in
= a + b + c
= end;
h
g
f
val it = 6 : int
- let
= fun f _ = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= fun a() = print "a\n"
= fun b() = print "b\n"
= val (c, d, e) = (f [a(), b()], g(), h())
= in
= c + d + e
= end;
a
b
f
g
h
val it = 6 : int
Be aware that, in OCaml, due to the (relaxation of the) value restriction, let a = b in c is not equivalent to (fun a -> c)b. A counterexample is
# let id = fun x -> x in id 5, id 'a';;
- : int * char = (5, 'a')
# (fun id -> id 5, id 'a')(fun x -> x)
Error: This expression has type char but an expression was expected of type int
#
This means that they are semantically not the same construction (the let ... = ... in ... is strictly more general that the other).
This happens because, in general, the type system of OCaml doesn't allow types of the form (โˆ€ฮฑ.ฮฑโ†’ฮฑ) โ†’ int * char (because allowing them would make typing undecidable, which is not very practical), which would be the type of fun id -> id 5, id 'a'. Instead, it resorts to having the less general type โˆ€ฮฑ.(ฮฑโ†’ฮฑ) โ†’ ฮฑ * ฮฑ, which doesn't make it typecheck, because you can't unify both ฮฑ with char and with int.

Handling nested records of lists in f#

I am currently having some trouble elegantly handling nested record lists.
lets say we have the types:
type BoxEntry = {
flag : bool
}
type Box = {
entries : BoxEntry list
}
type Entry = {
boxes : Box list
}
type Model = {
recEntries : Entry list
}
Now lets say I want to set a specific boxentry bool I have the list indexes of Entry, Box and BoxEntry however I have only found this approach to work for me:
let handleUnsetEntry (model : Model) (idxs : string* int * int) =
let(sendId, bi, ej) = idxs
let nEntry =
model.entries
|> List.map(fun x ->
if x.sendId = sendId then
{x with boxes =
x.boxes |> List.mapi (fun i y ->
if i = bi then
{y with boxEntry =
y.boxEntry |> List.mapi (fun j z ->
if j = ej then
z.SetFlag
else
z)}
else
y)}
else
x)
{model with entries = nEntry}, Cmd.none
This is obviously a really silly solution both efficiency-wise as well as readability-wise. Is there another approach to this which is more elegant I feel like there surely must be but I am not getting it.
Any help would be appreciated.
In FP there's a pattern called Lens or Prism. It's kind of composable functional attributes to simplify handling of nested immutable structures.
Lenses/Prisms allows you to zoom in on a nested attribute and get/set it while preserving immutability (set returns a new object).
Lenses/Prisms doesn't really answer what to do IIRC with structures that contains lists but if we ignore that and "hack something" we could end up with something like this:
type Prism<'O, 'I> = P of ('O -> 'I option)*('O -> 'I -> 'O)
That is, a prism consists of two functions; a getter and a setter. The getter given an outer value returns the inner value if it exists. The setter creates a new outer value given a new inner value.
This allows us too define the commonly used fstL and sndL prisms that allows zooming on the first respectively the second part of a pair.
let fstL =
let g o = o |> fst |> Some
let s (_, s) i = (i, s)
P (g, s)
let sndL =
let g o = o |> snd |> Some
let s (f, _) i = (f, i)
P (g, s)
We also define a way to combine two prisms
// Combines two prisms into one
let combineL (P (lg, ls)) (P (rg, rs)) =
let g o =
match lg o with
| None -> None
| Some io -> rg io
let s o i =
match lg o with
| None -> o
| Some io -> ls o (rs io i)
P (g, s)
let (>->) l r = combine l r
Using this we can define a prism that allows zooming into a rather complex structure:
let l = sndL >-> sndL >-> fstL
let o = (1, (2, (3, 4)))
get l o |> printfn "%A" //Prints 3
let o = set l o 33
get l o |> printfn "%A" //Prints 33
Given the Model given by OP we extend it with Prisms static attributes
type BoxEntry =
{
flag : bool
}
member x.SetFlag = {x with flag = true}
// Prisms requires some boiler plate code, this could be generated
static member flagL =
let g (o : BoxEntry) = Some o.flag
let s (o : BoxEntry) i = { o with flag = i }
P (g, s)
Putting it all together we can rewrite the handle function to something like this:
let handleUnsetEntry (model : Model) (idxs : string* int * int) =
let (sendId, bi, ej) = idxs
// Builds a Prism to the nested flag
let nestedFlagL =
Model.entriesL
>-> Prism.listElementL (fun _ (e : Entry) -> e.sendId) sendId
>-> Entry.boxesL
>-> Prism.listElementAtL bi
>-> Box.boxEntryL
>-> Prism.listElementAtL ej
>-> BoxEntry.flagL
Prism.set nestedFlagL model true
Hope this gave OP some ideas on how one can handle nested immutable structures.
The full source code:
// A Prism is a composable optionally available property
// It consist of a getter function that given an outer object returns
// the inner object if it's there
// Also a setter function that allows setting the inner object
// (if there's a feasible place)
// In FP there are patterns called Lens and Prisms, this is kind of a bastard Prism
type Prism<'O, 'I> = P of ('O -> 'I option)*('O -> 'I -> 'O)
module Prism =
let get (P (g, _)) o = g o
let set (P (_, s)) o i = s o i
let fstL =
let g o = o |> fst |> Some
let s (_, s) i = (i, s)
P (g, s)
let sndL =
let g o = o |> snd |> Some
let s (f, _) i = (f, i)
P (g, s)
// Combines two prisms into one
let combineL (P (lg, ls)) (P (rg, rs)) =
let g o =
match lg o with
| None -> None
| Some io -> rg io
let s o i =
match lg o with
| None -> o
| Some io -> ls o (rs io i)
P (g, s)
// Creates a Prism for accessing a listElement
let listElementL sel k =
let g o =
o
|> List.mapi (fun i v -> (sel i v), v)
|> List.tryPick (fun (kk, vv) -> if k = kk then Some vv else None)
let s o i =
o
|> List.mapi (fun i v -> (sel i v), v)
|> List.map (fun (kk, vv) -> if k = kk then i else vv)
P (g, s)
let listElementAtL i =
listElementL (fun j _ -> j) i
type Prism<'O, 'I> with
static member (>->) (l, r) = Prism.combineL l r
// Modified model to match the code in OPs post
type BoxEntry =
{
flag : bool
}
member x.SetFlag = {x with flag = true}
// Prisms requires some boiler plate code, this could be generated
static member flagL =
let g (o : BoxEntry) = Some o.flag
let s (o : BoxEntry) i = { o with flag = i }
P (g, s)
type Box =
{
boxEntry : BoxEntry list
}
static member boxEntryL =
let g (o : Box) = Some o.boxEntry
let s (o : Box) i = { o with boxEntry = i }
P (g, s)
type Entry =
{
sendId : string
boxes : Box list
}
static member sendIdL =
let g (o : Entry) = Some o.sendId
let s (o : Entry) i = { o with sendId = i }
P (g, s)
static member boxesL =
let g (o : Entry) = Some o.boxes
let s (o : Entry) i = { o with boxes = i }
P (g, s)
type Model =
{
entries : Entry list
}
static member entriesL =
let g (o : Model) = Some o.entries
let s (o : Model) i = { o with entries = i }
P (g, s)
let handleUnsetEntry (model : Model) (idxs : string* int * int) =
let (sendId, bi, ej) = idxs
// Builds a Prism to the nested flag
let nestedFlagL =
Model.entriesL
>-> Prism.listElementL (fun _ (e : Entry) -> e.sendId) sendId
>-> Entry.boxesL
>-> Prism.listElementAtL bi
>-> Box.boxEntryL
>-> Prism.listElementAtL ej
>-> BoxEntry.flagL
Prism.set nestedFlagL model true
[<EntryPoint>]
let main argv =
let model : Model =
{
entries =
[
{
sendId = "123"
boxes =
[
{
boxEntry =
[
{
flag = false
}
{
flag = false
}
]
}
]
}
]
}
printfn "Before change"
printfn "%A" model
let model = handleUnsetEntry model ("123", 0, 0)
printfn "After 1st change"
printfn "%A" model
let model = handleUnsetEntry model ("123", 0, 1)
printfn "After 2nd change"
printfn "%A" model
let model = handleUnsetEntry model ("Hello?", 0, 1)
printfn "After missed change"
printfn "%A" model
0

using record field in other field of the same record

I wonder if it is possible in OCaml to use one field of record in the other field in the same record.
Basicaly, I have field with function in which I would like to use also other, values, fields of the same record so when the value change the function will use the new value.
I can do it with setting the function field mutable and update it after the record is created e.g.
type 'a cell =
{ mutable value: 'a
; mutable fn: unit -> 'a }
let create_cell ~(value : 'a) : 'a cell =
let c = {value; fn= (fun () -> value + 42)} in
let _ = c.fn <- (fun () -> c.value + 42) in
c
I was wondering if it is possible without fn field being mutable and in one go.
You can use let rec to make the function refer to the record it is part of:
# type 'a cell = { mutable value : 'a ; fn : unit -> 'a };;
type 'a cell = { mutable value : 'a; fn : unit -> 'a; }
# let rec r = { value = 14; fn = fun () -> r.value + 14 };;
val r : int cell = {value = 14; fn = <fun>}
# r.fn ();;
- : int = 28
# r.value <- 10;;
- : unit = ()
# r.fn ();;
- : int = 24
If I understand correctly, this what you'd like to do.
So then your create_cell function might look like this:
let create_cell ~(value : 'a) : 'a cell =
let rec c = {value; fn= (fun () -> c.value + 42)} in
c
It seems to work:
# let mycell = create_cell ~value: 88;;
val mycell : int cell = {value = 88; fn = <fun>}
# mycell.fn ();;
- : int = 130
# mycell.value <- 100;;
- : unit = ()
# mycell.fn ();;
- : int = 142

Is it possible to garantee the consistency of memoization?

I want to build a module I with memoization. The type I.t contains a real complex content c, and some mutable properties (eg, mutable is_cool). The module provides outside with functions to calculate and get the properties (eg, is_cool), which can be costly, that is why mutable properties are used:
(*in i.ml *)
module Content = struct
type t = { i: int; mutable j: int }
let is_cool (x: t) : bool = ...
end
module I : sig
type t
val get_c: t -> Content.t
val is_cool: t -> bool
...
end = struct
type t = {
c : Content.t;
mutable is_cool : bool option;
mutable property_a : int option }
let get_c (x: t) -> Content.t = x.c
let is_cool (x: t) : bool =
match x.is_cool with
| Some r -> r
| None -> (* not yet calculated *)
let r = Content.is_cool x.c in
x.is_cool <- Some r;
r
end
...
A concern that I have, is how to code the module I and the code outside such that for any value of type I.t throughout the program execution, its mutable properties are always consistent with its content c. Being consistent means "the mutable properties should either be None or be Some v where v represents the current property of the content".
For instance, the following code tempting to modify directly a property is well forbidden by the signature of the module I.t:
(* in main.ml *)
open I
let test (x: I.t) =
x.is_cool <- Some false
However, it seems that it is not easy to forbid this code, which changes the content:
(* in main.ml *)
let test (x: I.t) (i_new: int) =
let c = I.get_c x in
let c_new = { c with Content.i = i_new } in
let y = { x with c = c_new } in
(* now the content and the properties in y are likely to be inconsistent *)
One way to improve this is to add set in the module I, and always use set x c_new at the place of { x with c = c_new }:
(*in i.ml *)
let set (x: t) (c: Content.t) : t =
{ c = c; is_cool = None; property_a = None }
However, there are still problems, for instance,
1) it is still impossible to forbid people from writing { x with c = c_new }
2) a modification of the mutable components in Content.t (eg, mutable j: int) can also make I.t inconsistent:
(* in main.ml *)
let test (x: I.t) (j_new: int) =
let c = I.get_c x in
c.Content.j <- j_new;
(* now the content and the properties in x are likely to be inconsistent *)
Does anyone know any existing reflexion or solution face to this inconsistency caused by memoization? If we always use set at the place of "record with", and do not allow mutable components in Content.t, can we guarantee 100% the consistency for any code scenario?
Well, you could use private
Your code would look like this :
module type C = sig
type t = private { i: int; mutable j: int }
val new_c : int -> int -> t
val is_cool : t -> bool
end
module Content : C = struct
type t = { i: int; mutable j: int }
let new_c = ...
let is_cool (x: t) : bool = ...
end
module I : sig
type t
val new_i : int -> int -> t
val get_c: t -> Content.t
val is_cool: t -> bool
...
end = struct
type t = {
c : Content.t;
mutable is_cool : bool option;
mutable property_a : int option }
let new_i = ...
let get_c (x: t) -> Content.t = x.c
let is_cool (x: t) : bool =
match x.is_cool with
| Some r -> r
| None -> (* not yet calculated *)
let r = Content.is_cool x.c in
x.is_cool <- Some r;
r
end
...
And if you try to write :
let c = {i = 3; j = 3};;
it will reject you answering :
Error: Cannot create values of the private type Content.t

Is this a case where I need a functor?

I'm using the Bitstring module in the following code:
let build_data_32 v wid =
let num = wid / 32 in
let v' = Int32.of_int(v) in
let rec aux lst vv w = match w with
0 -> lst
| _ -> (BITSTRING { vv : 32 } ) :: ( aux lst (Int32.succ vv) (w-1)) in
Bitstring.concat ( aux [] v' num ) ;;
Note that when you have BITSTRING { vv : 32 }
that vv is expected to be an Int32 value. I'd like to generalize this function to work with different widths of bitstrings; ie, I'd like to create a build_data_n function where the bitstring would be constructied with BITSTRING { vv : n } .
However, the problem here is that if n is less than 32 then the succ function used above would just be the succ for type int. If it's greater than 32 it would be Int64.succ Same issue above in the line let v' = Int32.of_int(v) in - for values less than 32 it would simply be: let v' = v in , whereas for values greater than 32 it would be: let v' = Int64.of_int(v) in
Is this a case where a functor would come in handy to generalize this function and if so, how would I set that up? (and if there's some other way to do this that doesn't require functors, that would be nice to know as well)
There are a few approaches available. One is to use a functor, similar to the following:
(* The signature a module needs to match for use below *)
module type S = sig
type t
val succ : t -> t
val of_int : int -> t
end
(* The functor *)
module Make(M : S) = struct
(* You could "open M" here if you wanted to save some typing *)
let build_data v =
M.succ (M.of_int v)
end
(* Making modules with the functor *)
module Implementation32 = Make(Int32)
module Implementation64 = Make(Int64)
let foo32 = Implementation32.build_data 12
let foo64 = Implementation64.build_data 12
Another is to wrap your data type in a record:
(* A record to hold the relevant functions *)
type 'a wrapper_t = { x : 'a; succ : 'a -> 'a }
(* Use values of type 'a wrapper_t in *)
let build_data v =
v.succ v.x
(* Helper function to create 'a wrapper_t values *)
let make_int32_wrapper x = { x = Int32.of_int x; succ = Int32.succ }
let make_int64_wrapper x = { x = Int64.of_int x; succ = Int64.succ }
(* Do something with a wrapped int32 *)
let foo32 = build_data (make_int32_wrapper 12)
let foo64 = build_data (make_int64_wrapper 12)
And finally, if you are using OCaml 3.12.0 or later, you can use first class modules:
(* You can use the module type S from the first example here *)
let build_data (type s) m x =
let module M = (val m : S with type t = s) in
M.succ x
let int32_s = (module Int32 : S with type t = Int32.t)
let int64_s = (module Int64 : S with type t = Int64.t)
let foo32 = build_data int32_s 12l
let foo64 = build_data int64_s 12L
Each of these approaches can be mixed and matched. You may also be able to wrap your values in variant types or objects to get a similar result.
With BITSTRING { vv : n }, i.e. using runtime-specified field length, the type of vv cannot depend on n as it is not the compile-time constant anymore, so vv is forced to int64.