<div dir="ltr">Thanks, David! That looks exactly like what I have in mind. Given its dependency on primitive and primitive not being a part of base (or a boot lib), I think I'd better give up upstreaming the idea and simply use that package when really needed.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Nov 11, 2020 at 10:36 PM David Feuer <<a href="mailto:david.feuer@gmail.com">david.feuer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">You should look at the primitive-unlifted package which offers a class for wrapping and unwrapping unlifted things and functions for making weak pointers from (and to) unlifted things.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Nov 11, 2020, 4:34 PM Cheng Shao <<a href="mailto:astrohavoc@gmail.com" target="_blank">astrohavoc@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi everyone,<br><br>In System.Mem.Weak we have an mkWeak function to create weak pointers. But we<br>also have a lot of specialized mkWeak* functions, e.g. mkWeakIORef,<br>mkWeakThreadId, etc, to ensure that we actually pass the unlifted closure<br>instead of the lifted one as the key to the underlying mkWeak# primop.<br><br>The various specialized mkWeak* functions' signatures don't have a coherent<br>style. Some functions like mkWeakIORef always take a Haskell finalizer argument,<br>while mkWeakThreadId doesn't take a finalizer argument at all. This is<br>troublesome for users since:<br><br>* Sometimes a user doesn't want to attach a finalizer at all. They could pass a<br>"pure ()" dummy finalizer, but that'll still come with a minor bit of extra<br>runtime overhead<br><br>* For mkWeakThreadId, they may want to attach a finalizer. The runtime supports<br>it, but the type signature doesn't say so.<br><br>Of course, they can always add a few extensions and call mkWeak# as they wish,<br>but it would be nicer if we have a uniform API to allow a Haskell finalizer to<br>be added optionally. The simplest API could be something like (forgive my<br>terrible naming):<br><br>class WeakKey k where<br> mkWeakWithRealKey :: WeakKey k => k -> v -> Maybe (IO ()) -> IO (Weak v)<br><br>The WeakKey class is just a way of exposing the unlifted field from a single<br>datacon wrapper type, and I think this can be useful for other purposes as well,<br>so maybe we can do something like:<br><br>class Unlift a where<br> type Unlifted a :: TYPE 'UnliftedRep<br> unlift :: a -> Unlifted a<br><br>mkWeakWithRealKey :: Unlift k => k -> v -> Maybe (IO ()) -> IO (Weak v)<br><br>Thanks for reading so far, what are your thoughts on this? The proposed extended<br>interfaces can be easily implemented in 3rd-party packages, but it would be nice<br>to add to base.<br><br>Cheers,<br>Cheng Shao<br></div>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" rel="noreferrer" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>
</blockquote></div>