<div dir="auto"><div>Unfortunately not. The type the type checker is told for the `atomicModifyMutVar2#` primop is a lie (too permissive). The type documented in its Haddocks is also a lie (too restrictive). Its most precise type, as I understand it, is (translating away the unboxed stuff and the internal I/O representation)<div dir="auto"><br></div><div dir="auto">atomicModifyMutVar2</div><div dir="auto">  :: IORef a<br></div><div dir="auto">  -> (a -> t)</div><div dir="auto">  -> IO (a, t)</div><div dir="auto">-- with the condition that `t` is a record whose first field that is represented by a pointer (what we call BoxedRep) has a type with the same memory representation as `a`.</div><div dir="auto"><br></div><div dir="auto">While it would be possible to express that fairly precisely using the Generics approach, I think it's too hard to think about "the first pointer field", and the "same memory representation" bit mucks with type inference. So I restricted it a little to "the first field, which must be a pointer", and "with type `a`".</div><div dir="auto"><br></div><div dir="auto">There's a sort of "hidden unsafeCoerce" in the primop call, where we know that the "selector thunk" it builds (a thunk applying a record selector, in this case fst) will extract the field we want out of what we give it. The type checker is clueless and just accepts whatever.</div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 10, 2023, 4:09 AM Tom Smeding <<a href="mailto:x@tomsmeding.com">x@tomsmeding.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div>
    I'm not the person to ask :) Maybe someone else on the list can chip
    in here.<br>
    <br>
    Another question if you don't mind (I'm learning here): you say
    below that in <a id="m_-4214265619866510319v:atomicModifyIORef2Native" rel="noreferrer">atomicModifyIORef2Native,</a>
    you rely on heap object layout to unsafeCoerce between a pair and
    any object with an interesting value in the first field. But looking
    at the source [1], it seems you only do this for base < 4.13,
    i.e. GHC < 8.8.4. That's been a while.<br>
    <br>
    Is it true that for GHCs since 8.8.4 you can just use a primop to do
    what you want directly, without the magic Generic stuff? If so,
    perhaps you can even drop the Generic constraints for high enough
    GHC versions (by extending the scope of the CPP slightly)? 8.6.5 is
    still popular, but simultaneously a whole bunch of applications
    don't care about GHCs <9 anymore.<br>
    <br>
    - Tom<br>
    <br>
    [1]:
<a href="https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0/docs/src/Data.IORef.AtomicModify.Generic.html#atomicModifyIORef2Native" target="_blank" rel="noreferrer">https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0/docs/src/Data.IORef.AtomicModify.Generic.html#atomicModifyIORef2Native</a><br>
    <br>
    <div>On 10/03/2023 09:45, David Feuer wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="auto">Whoops! Thanks for pointing that out. I'll fix it
        and push new docs. There's not much magic in that part of the
        code itself; the nasty magic is knowing that the first pointer
        in any record is in the same position in its heap object as the
        first component of a pair. Speaking of which, do you have any
        idea if it'll work for non-record types whose constructors all
        have the same first field? I'm guessing yes, but I haven't
        experimented yet.</div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Fri, Mar 10, 2023, 3:27 AM
          Tom Smeding <<a href="mailto:x@tomsmeding.com" target="_blank" rel="noreferrer">x@tomsmeding.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi David,<br>
          <br>
          Fancy stuffs!<br>
          <br>
          Wondering how much magic was going on in implementing this, I
          saw that <br>
          atomicModifyIORef2Native misses the haddock marker '|' in the
          source; <br>
          thus your extensive doc comment doesn't show up on hackage.<br>
          <br>
          Cheers,<br>
          Tom<br>
          <br>
          On 10/03/2023 03:01, David Feuer wrote:<br>
          > I just put together a new package, atomic-modify-general,
          for<br>
          > generalizations of the `atomicModifyIORef` operation. In
          particular:<br>
          ><br>
          > 1. Versions that allow a result of an arbitrary type (not
          necessarily<br>
          > a pair), where the caller passes in an extraction
          function. These work<br>
          > with `Array` and `SmallArray` from `primitive` as well as
          `IORef`.<br>
          > 2. A version that works with record types (not just
          pairs) whose first<br>
          > field is the new value to install in the `IORef`. This
          uses<br>
          > implementation details of the `atomicModifyMutVar#`
          primop as well as<br>
          > GHC's heap object layout to achieve better performance.<br>
          ><br>
          > Please try it out and let me know how it goes, and what
          extras you may want!<br>
          ><br>
          > Hackage: <a href="https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0" rel="noreferrer noreferrer noreferrer" target="_blank">https://hackage.haskell.org/package/atomic-modify-general-0.1.0.0</a><br>
          > _______________________________________________<br>
          > Haskell-Cafe mailing list<br>
          > To (un)subscribe, modify options or view archives go to:<br>
          > <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
          > Only members subscribed via the mailman list are allowed
          to post.<br>
          <br>
          _______________________________________________<br>
          Haskell-Cafe mailing list<br>
          To (un)subscribe, modify options or view archives go to:<br>
          <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
          Only members subscribed via the mailman list are allowed to
          post.</blockquote>
      </div>
    </blockquote>
    <br>
  </div>

</blockquote></div></div></div>