<div dir="ltr">Hi Hécate and David,<br><div><br></div><div>I'm in support of this proposal. And the module name "Data.Newtype" sounds good to me 👍</div><div><br></div><div>I specifically like the "un" function because it helps to reduce unnecessary boilerplate. If you have a newtype, it's convenient to specify an unwrapping function, e.g.</div><div><br></div><div>newtype Size = Size</div><div>    { unSize :: Int</div><div>    }</div><div><br></div><div>But then, it becomes awkward in two scenarios:</div><div><br></div><div>1. When newtypes are long, e.g. "PasswordHash".</div><div>2. When you rename newtypes, you also need to rename the unwrapping function. While renaming the constructor makes total sense to me, because you want to be explicit in what particular newtype you wrap your values, renaming the unwrapping function looks to me like maintaining the unnecessary boilerplate.</div><div><br></div><div>Type inference is a valid concern, but those functions are opt-in, and if people are worried about type inference, they can use type applications or good old record fields. Also, the order of type variables for the implementations from "Relude" is optimized for usage with "TypeApplications", so it's quite convenient to wrap and unwrap newtypes.</div><div><br></div><div>Best regards,</div><div>Dmitrii</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 11 Nov 2020 at 10:01, Hécate <<a href="mailto:hecate@glitchbra.in">hecate@glitchbra.in</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>
    <p>Do you think that they will produce unwanted inference even with
      -XTypeApplications?<br>
    </p>
    <div>Le 11/11/2020 à 08:42, David Feuer a
      écrit :<br>
    </div>
    <blockquote type="cite">
      
      <div dir="auto">For the most part, I oppose adding these to base.
        I'm most sympathetic to adding (.#) and (#.), originally from
        the profunctors package, as they seem to pop up quite a lot. For
        the rest, inference can be a real problem. coercible-utils goes
        to quite a lot of trouble to make these functions reasonably
        usable, but I don't think we want that sort of machinery in
        `base`. </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, Nov 10, 2020, 8:23 AM
          Hécate <<a href="mailto:hecate@glitchbra.in" target="_blank">hecate@glitchbra.in</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>
            <p>Hello, CLC and haskell-libraries,<br>
              <br>
              I am opening a proposal process to consider the
              integration of several helper functions in `base`,
              operating on Newtypes, and all based on `coerce`.<br>
              <br>
              My motivations are that we ought to provide a minimum set
              of tools in order to work effectively with one of our most
              beloved and ubiquitous language features.<br>
              <br>
              Now, these functions that I am about to present to you all
              do not come out of nowhere. They have been integrated to
              Kowainik's alternative prelude "Relude", and seem<br>
              to have found their use amongst their users, me included.<br>
              Their documentation can be found here =>
              <a href="https://hackage.haskell.org/package/relude-0.7.0.0/docs/Relude-Extra-Newtype.html" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/relude-0.7.0.0/docs/Relude-Extra-Newtype.html</a>
              <br>
              but I am reproducing them below for convenience:<br>
              <br>
              ---<br>
              <a id="gmail-m_4782239641169241119m_4016565528343698598v:un" rel="noreferrer">un :: forall a n. Coercible a n
                => n -> a<br>
                <br>
                Unwraps value from newtype.<br>
                <br>
                ```<br>
                >>> newtype Size = Size Int deriving Show<br>
                >>> un @Int (Size 5)<br>
                5<br>
                >>> un (Size 5) == length ['a', 'x', 'b']<br>
                False<br>
                ```<br>
                <br>
              </a>---<br>
              wrap :: forall n a. Coercible a n => a -> n <br>
              <br>
              Wraps value to newtype. Behaves exactly as 'un' but has
              more meaningful name in case you need to convert some
              value to newtype.<br>
              <br>
              ```<br>
              >>> newtype Flag = Flag Bool deriving (Show, Eq)<br>
              >>> wrap False == Flag True<br>
              False<br>
              ```<br>
            </p>
            <p>---<br>
              under :: forall n a. Coercible a n => (n -> n) ->
              a -> a<br>
              <br>
              Applies function to the content of newtype. This function
              is not supposed to be used on newtypes that are created
              with the help of smart constructors.<br>
              <br>
              ```<br>
              >>> newtype Foo = Foo Bool deriving Show<br>
              >>> under not (Foo True)<br>
              Foo False<br>
              >>> newtype Bar = Bar String deriving Show<br>
              >>> under (filter (== 'a')) (Bar "abacaba")<br>
              Bar "aaaa"<br>
              ```<br>
              <br>
              As well as the coerced composition operator:<br>
              <br>
              (#.) :: Coercible b c => (b -> c) -> (a -> b)
              -> (a -> c)<br>
              (#.) _f = coerce<br>
              {-# INLINE (#.) #-}<br>
              <br>
              Which currently lives in
              <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data.Functor.Utils.html#%23" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data.Functor.Utils.html#%23</a>
              but is not exported.<br>
              <br>
              <br>
              Regarding the location of these functions, I either see
              them living in their own "Data.Newtype", or they could
              join Data.Coerce.<br>
              I would personally create a new module as to avoid
              "polluting" Data.Coerce with non-class functions, but this
              is my personal preference.<br>
              <br>
              <br>
              Thank you for reading.<br>
              <br>
            </p>
            <pre cols="72">-- 
Hécate ✨
🐦: @TechnoEmpress
IRC: Uniaika
WWW: <a href="https://glitchbra.in" rel="noreferrer" target="_blank">https://glitchbra.in</a>
RUN: BSD</pre>
          </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>
    <pre cols="72">-- 
Hécate ✨
🐦: @TechnoEmpress
IRC: Uniaika
WWW: <a href="https://glitchbra.in" target="_blank">https://glitchbra.in</a>
RUN: BSD</pre>
  </div>

_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>