<div>Thank you for suggesting these, Hécate.</div><div><br></div><div>I personally don't see much benefit in `un` and `wrap` functions, since it is quite straightforward to use coerce directly:<br></div><div><br></div><div>un @Int = coerce @_ @Int<br></div><div><br></div><div>and wrap is the same way:<br></div><div><br></div><div>wrap @SIze = coerce @_ @Size<br></div><div><br></div><div>At what point do we stop creating synonyms? Adding these two functions IMHO is a redundant mental overhead. <br></div><div><br></div><div>On the other hand `#.` operator can be quite handy and I'd be totally in favor of exposing it to the world but from a Data.Coerce module instead of a totally new module. However I would also not call it coerced composition operator, because firstly it doesn't really compose functions it just coerces them and secondly it can be made more polymorphic and then it would be useful with other things than just functions:<br></div><div><br></div><div>(#.) :: forall a b c proxy. Coercible b c => proxy b c -> (a -> b) -> (a -> c)<br></div><div>(#.) _proxy = coerce<br></div><div><br></div><div>With regards to `under` I am a somewhat indifferent, but if it was in base I am sure I'd use it. Naming is a bit odd, but I am not the one to bikeshed.<br></div><div><br></div><div>Sincerely,<br></div><div>Alexey.<br></div><div><br></div><div>‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐<br></div><div> On Tuesday, November 10, 2020 4:23 PM, Hécate <hecate@glitchbra.in> wrote:<br></div><div> <br></div><blockquote class="protonmail_quote" type="cite"><p><br></p><div>Hello, CLC and haskell-libraries,<br></div><div> <br></div><div> 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></div><div> <br></div><div> 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></div><div> <br></div><div> 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></div><div> to have found their use amongst their users, me included.<br></div><div> Their documentation can be found here => <a href="https://hackage.haskell.org/package/relude-0.7.0.0/docs/Relude-Extra-Newtype.html">https://hackage.haskell.org/package/relude-0.7.0.0/docs/Relude-Extra-Newtype.html</a> <br></div><div> but I am reproducing them below for convenience:<br></div><div> <br></div><div> ---<br></div><div> <a>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>---</div><div> wrap :: forall n a. Coercible a n => a -> n <br></div><div> <br></div><div> Wraps value to newtype. Behaves exactly as 'un' but has more
meaningful name in case you need to convert some value to newtype.<br></div><div> <br></div><div> ```<br></div><div> >>> newtype Flag = Flag Bool deriving (Show, Eq)<br></div><div> >>> wrap False == Flag True<br></div><div> False<br></div><div> ```<br></div><p><br></p><p><br></p><div>---<br></div><div> under :: forall n a. Coercible a n => (n -> n) -> a ->
a<br></div><div> <br></div><div> 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></div><div> <br></div><div> ```<br></div><div> >>> newtype Foo = Foo Bool deriving Show<br></div><div> >>> under not (Foo True)<br></div><div> Foo False<br></div><div> >>> newtype Bar = Bar String deriving Show<br></div><div> >>> under (filter (== 'a')) (Bar "abacaba")<br></div><div> Bar "aaaa"<br></div><div> ```<br></div><div> <br></div><div> As well as the coerced composition operator:<br></div><div> <br></div><div> (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a
-> c)<br></div><div> (#.) _f = coerce<br></div><div> {-# INLINE (#.) #-}<br></div><div> <br></div><div> Which currently lives in <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data.Functor.Utils.html#%23">https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data.Functor.Utils.html#%23</a> but is not exported.<br></div><div> <br></div><div> <br></div><div> Regarding the location of these functions, I either see them
living in their own "Data.Newtype", or they could join
Data.Coerce.<br></div><div> I would personally create a new module as to avoid "polluting"
Data.Coerce with non-class functions, but this is my personal
preference.<br></div><div> <br></div><div> <br></div><div> Thank you for reading.<br></div><div> <br></div><p><br></p><pre cols="72">--
Hécate ✨
🐦: @TechnoEmpress
IRC: Uniaika
WWW: <a href="https://glitchbra.in">https://glitchbra.in</a>
RUN: BSD<br></pre></blockquote><div><br></div>