Map mashing function

David Feuer david.feuer at gmail.com
Mon Aug 8 16:20:06 UTC 2016


I was wrong. It's possible to write the general safe merge function in
Haskell 98, by replacing the GADT with a record of functions. Sorry for the
confusion!

On Aug 8, 2016 11:08 AM, "Edward Kmett" <ekmett at gmail.com> wrote:

> You could always bury the GADT in an internal module with whatever
> super-general API you expose that uses it. ;)
>
> Then I can have a sexy profunctor instance.
>
> -Edward
>
> On Mon, Aug 8, 2016 at 10:55 AM, Ryan Trinkle <ryan.trinkle at gmail.com>
> wrote:
>
>> Ah, that sounds interesting!  I'm not really sure there's much value to
>> exposing the GADT, so perhaps it would be better to keep it abstract.
>> Plus, you can always open it up later, but doing a deprecation cycle if you
>> decide it needs to be abstract will be super painful.  So i guess I'd tend
>> to think that abstract is the safer option.
>>
>> On Mon, Aug 8, 2016 at 10:28 AM, David Feuer <david.feuer at gmail.com>
>> wrote:
>>
>>> Thanks! One more question: should I export the GADT constructors, or
>>> just bindings for them? The (theoretical) advantage of the latter is that I
>>> can enforce equivalences
>>>
>>> dropC == mapFilterC (\_ _ -> Nothing)
>>>
>>> and
>>>
>>> preserveC == mapFilterC (\_ v -> Just v)
>>>
>>> I think this lets us write
>>>
>>> instance Functor f => Functor (MergeTactic f k v) where
>>>   fmap _ Drop = Drop
>>>   fmap f Preserve = MapFilter (\_ -> Just . f)
>>>   fmap f (MapFilter p) = MapFilter (\k x -> f <$> p k x)
>>>   fmap f (TraverseFilter p) = TraverseFilter (\k x -> fmap f <$> p k x)
>>>
>>> and I think this lets profunctors write
>>>
>>>
>>> instance Functor f => Profunctor (MergeTactic f k) where
>>>   dimap _ _ Drop = Drop
>>>   dimap f g Preserve = MapFilter (\_ -> Just . g . f)
>>>   dimap f g (MapFilter p) = MapFilter (\k x -> g <$> p k (f x))
>>>   dimap f g (TraverseFilter p) = TraverseFilter (\k x -> fmap g <$> p k
>>> (f x))
>>>
>>>
>>> On Aug 8, 2016 9:59 AM, "Ryan Trinkle" <ryan.trinkle at gmail.com> wrote:
>>>
>>>> Wow, that looks great!  I wasn't expecting something that clean or that
>>>> general.
>>>>
>>>> The choice of INLINE or INLINABLE is above my pay grade, but I'm sure
>>>> this will be a huge improvement either way!
>>>>
>>>> On Mon, Aug 8, 2016 at 9:48 AM, David Feuer <david.feuer at gmail.com>
>>>> wrote:
>>>>
>>>>> Is this good? https://github.com/haskell/con
>>>>> tainers/pull/317/files#diff-52bcc964836f9c44f05804a0c2267321R1904
>>>>>
>>>>> Ryan: I worked out a general map combining function, with some help
>>>>> from Dan Doel and Cale, that I think gets most of what you'd want from such
>>>>> a thing without the horrors of mergeWithKey.
>>>>>
>>>>> Both of you: I changed the Applicative actions to make sure they're
>>>>> entirely deterministic (going strictly in key order, interleaving actions
>>>>> associated with A-B, B-A, and A /\ B) without depending on tree balance. I
>>>>> decided that while it makes the most sense for the function to be in the
>>>>> middle, it's most convenient for it to be after the tactics, so I did that.
>>>>> If you disagree, let me know. Also, feedback on the type and constructor
>>>>> names would be great. Currently, the function is marked INLINE, like
>>>>> mergeWithKey. Should I mark it INLINABLE instead, and let users who want to
>>>>> be sure use an explicit `inline` call?
>>>>>
>>>>
>>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20160808/9e089331/attachment.html>


More information about the Libraries mailing list