
Sometimes there's an awkward expressive tension between saying that a type is *unboxed* and saying that it is *strict* in a field. For example, I can write data SMaybe a = SNothing | SJust !a or I can write type Maybe# a = (# (# #) | a #) but there doesn't seem to be a way to simultaneously get both unboxed and strict. I'm wondering if it might make sense to add a type to serve the purpose Strict# :: Type -> TYPE 'UnliftedRep mkStrict# :: a -> Strict# a -- force the argument getStrict# :: Strict# a -> a -- do nothing, but know the result is in WHNF Then one could write, for example, type SMaybe# a = (# (# #) | Strict# a #) at which point SMaybe is *precisely* isomorphic to the alternative representation data SMaybe' a = SMaybe' (SMaybe# a) David