I'm looking to do bad things. Is unsafe coercion a thing in Roc?
What is unsafe coercion?
I don't think it is a thing in roc
It's when you tell the type system what type a value has and it believes you unconditionally. It comes up (perhaps more legitimately) in FFI work (so I'm sure you could do it somehow by writing a custom platform (even if I'm not _really_ needing anything outside of Roc), maybe?). Not sure if that makes sense.
You can do anything you like if you write a platform, but from within roc land there is no way to express something like that I think.
The bad thing that I want to do is type constructor defunctionalisation/flatten out type constructors so that you can abstract over them.
While it's easy enough to have something like
Phantom t a := List a
ImAListIPromise := []
wrapList : List a -> Phantom ImAListIPromise a
wrapList = \la -> @Phantom la
unwrapList : Phantom ImAListIPromise a -> List a
unwrapList = \@Phantom la -> la
eventually you want
ImAFooIPromise := []
wrapFoo : Foo a -> Phantom ImAFooIPromise a
wrapFoo = ...
(as the whole point is to abstract over type constructors), but then you either need to have unbound type variables on the right
Phantom t a := unbound
(which doesn't work), or some mechanism for unsafe/forced type coercion.
Anytime you actually _use_ the values, you'd have to flip back and forth between the types (the real underlying type where you can operate on the value, and the opaque referencey/handle sort of type that you use to model type constructor abstraction (via proxy types))
I'm not sure whether it's a great idea (or cultural fit for Roc (given that real HKTs were explicitly and intentionally omitted)), but it feels like a fun exercise, at least. If you're interested in some background, https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf explains the approach. Here ImAListIPromise
is a brand; Phantom
is App
; and wrap*
and unwrap*
are inj
and prj
, respectively (which could probably be rolled into an Ability).
Last updated: Jul 06 2025 at 12:14 UTC