szkl has quit [Quit: Connection closed for inactivity]
waleee has quit [Ping timeout: 268 seconds]
tri has joined #ocaml
mbuf has joined #ocaml
zanetti has joined #ocaml
tri has quit [Remote host closed the connection]
zanetti has quit [Quit: zanetti]
mima has joined #ocaml
Serpent7776 has joined #ocaml
bartholin has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
dnh has joined #ocaml
sroso has quit [Read error: Connection reset by peer]
torretto has quit [Remote host closed the connection]
torretto has joined #ocaml
<discocaml>
<ozirm> Hi! I suspect what I need is impossible, but I'll ask anyway: is there a way to constrain a type variable to a set of concrete types? For example, I know that we can do `type 'a my_list = 'a list constraint 'a = (_ * _)` to make sure only pairs are valid inhabitants of `'a`, but is it possible to constrain `'a` to only unify with say `int` or `string`? Are there any other ways to achieve this that's not too boilerplate-heavy? I know it's possibl
<discocaml>
<andreypopp> Why is discuss in read only mode?
ocra8 has joined #ocaml
jabuxas has joined #ocaml
<discocaml>
<octachron> @ozirm : GADTs can be used to descrbie a finite set of type: `type 'a c = Int:int c`, `type 'a l = 'a c * 'a list`.
<discocaml>
<ozirm> @octachron: interesting, it's similar to tagging the list, except in this case we provide a witness of that type. I tried defining `type 'a l = 'b list constraint 'a = 'b c`, but it seems that the type-checker does not look into the possible constructors of `c`. That is, having `type 'a c = Int : int c | Bool : bool c`, I can still instantiate `let l : _ l = ["s"; "b"]`, for example.
<discocaml>
<ozirm> To give you some context I'm trying to model structural "union types" from the WebIDL spec where they are represented as `(float or boolean)`, for example. Preferably, I'd like to avoid wrapping these values to avoid any overhead in the bindings. So in essence, I'd like to be able to write a "partially" polymorphic function like `val f : 'float_or_boolean -> _`.
<discocaml>
<hockletock> you couldn't distinguish `false` and `true` from the tiny float values represented by 000....001 and 000...011 without at least wrapping the boolean
<discocaml>
<hockletock> wrapping the value*
<discocaml>
<_ggole> NaN-boxing is possible for that particular case, but that doesn't seem like a great idea
<discocaml>
<ozirm> @hockletock float and bool are just examples. So it would have to work for the general case.
<discocaml>
<leviroth> How are you planning to use these lists without some sort of tag to say what type the elements are?
tri has joined #ocaml
<discocaml>
<ozirm> These values are used to generate opaque javascript values. This means that it's totally safe to just pass them to the low-level runtime.
<discocaml>
<ozirm> I read the webidl files and generate OCaml modules that provide bindings to the described API for js_of_ocaml. In the above case, the `addEventListener` function needs to accept either a `AddEventListenerOptions` or a boolean for the `options` argument. Currently I'm wrapping these with poly variants, so the actual argument type becomes ``[`AddEventListenerOptions of AddEventListenerOptions.t | `Boolean of bool]``. This is ok, but ideally I'd pr
tri has quit [Remote host closed the connection]
<discocaml>
<deepspacejohn> An opaque value you pass to external code seems like a good use case for abstract types. If you want to avoid wrapping them in a polyvariant but still want the structural `or` logic that polyvariants provide, one option may be to cast them to an abstract type that's parameterized by a phantom polyvariant. https://ocaml.org/play#code=dHlwZSBhZGRFdmVudExpc3RlbmVyT3B0aW9ucyA9IHtmb286IHN0cmluZ30KCm1vZHVsZSBNIDogc2lnCiAgdHlwZSAnYSB0CiAgdmFsIG
<discocaml>
<hockletock> fr: discocaml turns code blocks into tinyurls of playground sessions
<companion_cube>
it's just matterbridge, I'm not going to modify it 😅
olle has quit [Ping timeout: 256 seconds]
tri has joined #ocaml
tri has quit [Ping timeout: 260 seconds]
<discocaml>
<ozirm> @deepspacejohn: that's pretty cool. I tried something similar with just `type t` for each union type and smart constructors, as in your suggestion. The tricky bit is that generating individual modules for each type that uses `or` is very cumbersome. The name of that module would be derived from each or-case ending up looking like `Node_or_trusted_script_or_dom_string`. And to call the function `Foo.append (Node_or_trusted_script_or_dom_string.do
<discocaml>
<ozirm> Another option, is to duplicate functions and specialize them for each `or` type as in `Foo.append_node`, `Foo.append_dom_string`, etc. Which is nicer, but would also blow up if there's multiple `or` types in the arguments.
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jabuxas has quit [Ping timeout: 245 seconds]
waleee has quit [Quit: WeeChat 4.1.2]
<discocaml>
<deepspacejohn> It seems like using polyvariants would eliminate the need to create a module for each possible combination of constructors? Since you would just need one ``val dom_string : string -> [> `Dom_string ] t``
<discocaml>
<deepspacejohn> Since `Node_or_trusted_script_or_dom_string.dom_string` and `Foo_or_bar_or_dom_string.dom_string` would both return the same ``[> `Dom_string ] t`` type.
tri has joined #ocaml
tri has quit [Ping timeout: 252 seconds]
jiquiame has quit [*.net *.split]
prgbln has quit [*.net *.split]
pi3ce has quit [*.net *.split]
end has quit [*.net *.split]
gentauro has quit [*.net *.split]
rom1504 has quit [*.net *.split]
gahr has quit [*.net *.split]
cr1901 has quit [*.net *.split]
discocaml has quit [*.net *.split]
ns12 has quit [*.net *.split]
pippijn has quit [*.net *.split]
Leonidas has quit [*.net *.split]
pie_ has quit [*.net *.split]
vsiles has quit [*.net *.split]
bacam has quit [*.net *.split]
buoy49__ has quit [*.net *.split]
hannes has quit [*.net *.split]
Ekho has quit [*.net *.split]
dinosaure has quit [*.net *.split]
Armael has quit [*.net *.split]
mima has quit [*.net *.split]
bcksl has quit [*.net *.split]
copy has quit [*.net *.split]
thizanne has quit [*.net *.split]
dme2 has quit [*.net *.split]
palainp has quit [*.net *.split]
johnel has quit [*.net *.split]
tri has joined #ocaml
waleee has joined #ocaml
johnel has joined #ocaml
dme2 has joined #ocaml
thizanne has joined #ocaml
copy has joined #ocaml
bcksl has joined #ocaml
mima has joined #ocaml
jiquiame has joined #ocaml
cr1901 has joined #ocaml
discocaml has joined #ocaml
ns12 has joined #ocaml
Leonidas has joined #ocaml
bacam has joined #ocaml
pie_ has joined #ocaml
vsiles has joined #ocaml
buoy49__ has joined #ocaml
hannes has joined #ocaml
Ekho has joined #ocaml
palainp has joined #ocaml
dinosaure has joined #ocaml
Armael has joined #ocaml
prgbln has joined #ocaml
pippijn has joined #ocaml
Armael has quit [Ping timeout: 268 seconds]
discocaml has quit [Excess Flood]
Armael has joined #ocaml
pi3ce has joined #ocaml
rom1504 has joined #ocaml
end has joined #ocaml
gentauro has joined #ocaml
gahr has joined #ocaml
tri has quit [Ping timeout: 268 seconds]
discocaml has joined #ocaml
pi3ce has quit [Max SendQ exceeded]
pi3ce has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
<discocaml>
<ozirm> You're right. With a smart constructor for each type, the polyvar becomes a phantom type instead of being an explict tag. I'll try that. Thank you!
waleee has joined #ocaml
mbuf has quit [Quit: Leaving]
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
dinosaure has quit [Ping timeout: 268 seconds]
dinosaure has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
Tuplanolla has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
dnh has joined #ocaml
bartholin has quit [Remote host closed the connection]
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
tri has joined #ocaml
jabuxas has joined #ocaml
tri has quit [Ping timeout: 240 seconds]
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
waleee has quit [Read error: Connection reset by peer]
waleee has joined #ocaml
tri has joined #ocaml
tri has quit [Remote host closed the connection]
waleee has quit [Read error: Connection reset by peer]
jabuxas has quit [Ping timeout: 246 seconds]
waleee has joined #ocaml
rgrinberg has joined #ocaml
tri has joined #ocaml
tri has quit [Ping timeout: 260 seconds]
tri has joined #ocaml
tri has quit [Ping timeout: 272 seconds]
tri has joined #ocaml
tri has quit [Ping timeout: 264 seconds]
torretto has quit [Ping timeout: 260 seconds]
motherfsck has quit [Ping timeout: 255 seconds]
torretto has joined #ocaml
tri has joined #ocaml
torretto has quit [Remote host closed the connection]
torretto has joined #ocaml
tri has quit [Ping timeout: 240 seconds]
Serpent7776 has quit [Ping timeout: 268 seconds]
motherfsck has joined #ocaml
bartholin has quit [Quit: Leaving]
dnh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<discocaml>
<ozirm> As an unrelated follow up to my previous question, I'm struggling to understand why the following code does not typecheck: ``module A : sig val f : [< `A | `B ] -> unit end = struct let f x = ignore [ x; `C ] end``. Is there a safe way to make `x` unify with additional variants?
<discocaml>
<ozirm> For instance, this open variant version on it's own ``let f (x : [> `A | `B ]) = ignore [ x; `C ]``, does typecheck. But if constrained with a module signature it fails.
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
mima has quit [Ping timeout: 240 seconds]
torretto has quit [Remote host closed the connection]
Tuplanolla has quit [Quit: Leaving.]
torretto has joined #ocaml
szkl has joined #ocaml
<discocaml>
<Kali> you flipped the order, did you mean to do that?
<discocaml>
<Kali> the first was < and now you used >
<discocaml>
<leviroth> This compiles: ``module A : sig val f : [< `A | `B ] -> unit end = struct let f x = ignore [ (x :> [ `A | `B | `C ]); `C ] end``
<discocaml>
<ozirm> @ilo_kali yes, since I'm confused by both not typechecking 🙂
<discocaml>
<ozirm> @therewolf Nice, thanks. In my real example, I have many additional tags, I guess I'll have to find a way to track them.