Stream: beginners

Topic: Unsafe coerce?


view this post on Zulip Jonathan Thiessen (Mar 15 2024 at 21:56):

I'm looking to do bad things. Is unsafe coercion a thing in Roc?

view this post on Zulip Luke Boswell (Mar 15 2024 at 22:25):

What is unsafe coercion?

view this post on Zulip Luke Boswell (Mar 15 2024 at 22:25):

I don't think it is a thing in roc

view this post on Zulip Jonathan Thiessen (Mar 15 2024 at 22:36):

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.

view this post on Zulip Luke Boswell (Mar 15 2024 at 22:41):

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.

view this post on Zulip Jonathan Thiessen (Mar 15 2024 at 22:55):

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.

view this post on Zulip Jonathan Thiessen (Mar 15 2024 at 23:10):

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))

view this post on Zulip Jonathan Thiessen (Mar 15 2024 at 23:18):

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