It is. However that doesn't give users the ability to solve this since -ffull-lazines allows GHC to potentially turn such a function into a thunk. One can disable full-laziness to avoid this, but you might like some things to be floated/shared and others to be constrained to a certain context rather than retaining them. Even if GHC would leave the function itself one might end up with code like: foo::Void#->T foo =... bar x y z = letr =foo void# in(f r,f r) Now foo itself is a "non-updatable thunk". But we capture it's result in an updatable thunk. Hence the need for the non-updatable attribute to be transitive in some fashion. Associating it with the return type might be one solution to address this. On 03/02/2026 13:34, Tom Ellis via ghc-devs wrote:
Isn't a function of type `(# #) -> T` already (isomorphic to) a "non-updatable thunk" of type T?
Tom
On Tue, Feb 03, 2026 at 11:43:48AM +0000, Simon Peyton Jones via ghc-devs wrote:
Hmm. So your proposal is:
- When declaring a type T, specify it as a "non-updatable type" - A thunk of type T is call-by-name
On Tue, 3 Feb 2026 at 08:25, Edsko de Vries
wrote: I think there *is* a better answer: I think (but this will require careful consideration) that the way is is to be able to mark certain types as "never update thunks of this type".
ghc-devs mailing list --ghc-devs@haskell.org To unsubscribe send an email toghc-devs-leave@haskell.org