<div dir="ltr">Note: this way of indicating which argument is unused means that this confusingly looks almost precisely backwards relative to the more general <a href="https://hackage.haskell.org/package/profunctors-5.2.2/docs/Data-Profunctor-Unsafe.html">code</a> that created those names and usage pattern in the first place. (I don't have a particularly strong objection to allowing the same sort of tweak to that code, assuming type inference works out in practice for the major consumers of the combinators there. I don't really foresee a problem, but I've been surprised by interactions before.)<br><br>I do have some concern that exporting these incompatible versions from Data.Coerce would break a subset of the code that is using the more general combinators in <font face="monospace, monospace">profunctors</font>. e.g. in the lens library these were coined for the code for prisms imports both.<div><br></div><div>This is why they were placed in a more obscure internal location to begin with as just the special case was needed by base and it was easier to write a copy locally than merge <font face="monospace, monospace">Profunctor</font> to base.<div><br></div><div>-Edward</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Apr 21, 2018 at 10:16 AM, Andrew Martin <span dir="ltr"><<a href="mailto:andrew.thaddeus@gmail.com" target="_blank">andrew.thaddeus@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Generalizing the type like that helps a lot. I had skimmed the documentation before, but I didn’t immediately comprehend what it meant. When I read the type signatures you gave them, it immediately made sense.<br>
<br>
Also, +1 on exporting these.<br>
<br>
Sent from my iPhone<br>
<div class="HOEnZb"><div class="h5"><br>
> On Apr 21, 2018, at 10:06 AM, Li-yao Xia <<a href="mailto:lysxia@gmail.com">lysxia@gmail.com</a>> wrote:<br>
> <br>
> That seems useful indeed! Using only 'coerce' requires too many type annotations.<br>
> <br>
> Would it make sense to generalize the type so it's clear that one argument is unused?<br>
> <br>
> (#.) :: Coercible b c => p b c -> (a -> b) -> (a -> c)<br>
> (.#) :: Coercible a b => (b -> c) -> p a b -> (a -> c)<br>
> <br>
> Li-yao<br>
> <br>
>> On 04/20/2018 03:56 PM, Daniel Cartwright wrote:<br>
>> (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)<br>
>> (#.) _ = coerce<br>
>> {-# INLINE (#.) #-}<br>
>> (.#) :: Coercible a b => (b -> c) -> (a -> b) -> (a -> c)<br>
>> (.#) f _ = coerce f<br>
>> {-# INLINE (.#) #-}<br>
>> The first of these is exported from Data.Functor.Util, and used in many<br>
>> places inside of base for efficiency over '.' (compose), However no module<br>
>> in base actually exports these. I have recently been using Data.Coerce more<br>
>> frequently and think it would be useful to go ahead and export these from<br>
>> somewhere in base.<br>
>> For convenience, I will paste the note about (#.) from Data.Functor.Util:<br>
>> "Note [Function coercion]<br>
>> ~~~~~~~~~~~~~~~~~~~~~~~<br>
>> Several functions here use (#.) instead of (.) to avoid potential efficiency<br>
>> problems relating to #7542. The problem, in a nutshell:<br>
>> If N is a newtype constructor, then N x will always have the same<br>
>> representation as x (something similar applies for a newtype deconstructor).<br>
>> However, if f is a function,<br>
>> N . f = \x -> N (f x)<br>
>> This looks almost the same as f, but the eta expansion lifts it--the lhs<br>
>> could<br>
>> be _|_, but the rhs never is. This can lead to very inefficient code. Thus<br>
>> we<br>
>> steal a technique from Shachaf and Edward Kmett and adapt it to the current<br>
>> (rather clean) setting. Instead of using N . f, we use N #. f, which is<br>
>> just<br>
>> coerce f `asTypeOf` (N . f)<br>
>> That is, we just *pretend* that f has the right type, and thanks to the<br>
>> safety<br>
>> of coerce, the type checker guarantees that nothing really goes wrong. We<br>
>> still<br>
>> have to be a bit careful, though: remember that #. completely ignores the<br>
>> *value* of its left operand.<br>
>> "<br>
>> -------------- next part --------------<br>
>> An HTML attachment was scrubbed...<br>
>> URL: <<a href="http://mail.haskell.org/pipermail/libraries/attachments/20180420/c5646504/attachment-0001.html" rel="noreferrer" target="_blank">http://mail.haskell.org/<wbr>pipermail/libraries/<wbr>attachments/20180420/c5646504/<wbr>attachment-0001.html</a>><br>
> ______________________________<wbr>_________________<br>
> Libraries mailing list<br>
> <a href="mailto:Libraries@haskell.org">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-<wbr>bin/mailman/listinfo/libraries</a><br>
______________________________<wbr>_________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org">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-<wbr>bin/mailman/listinfo/libraries</a><br>
</div></div></blockquote></div><br></div>