Open cies opened 6 years ago
I think the monomorphic nature of the typeclasses disallows a more general function to be written. I don't have any thoughts on how to do it, but if you or someone else can think of a way, I'm not opposed on principle.
On Wed, Apr 4, 2018 at 11:23 AM, Cies Breijs notifications@github.com wrote:
This errors out:
:set -XTypeFamilies :set -XNoImplicitPrelude :set -XFlexibleContexts :set -XOverloadedStrings :m ClassyPrelude let m = mapFromList ([("a", 1), ("b", 2)] :: [(Text, Int)]) mapWithKey (\k v -> k ++ tshow v) m
And it seems obvious why:
:t mapWithKey
Outputs:
mapWithKey :: IsMap map => (ContainerKey map -> MapValue map -> MapValue map) -> map -> map
So it can only map to exactly the same type of map. Very much what I'm not expecting from a map function in a higher-kinded language. Which would be:
map :: Functor f => (a -> b) -> f a -> f b
Allowing me (but obviously not forcing me) to change the type of map with mapping.
Is this restriction really needed? And, if yes, how do I get around it?
I'm now going the mapToList, processing, and then back with mapFromList, route.
I really like classy-prelude and all it brings me: thanks a lot for open source'ing and maintaining it!
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/snoyberg/mono-traversable/issues/162, or mute the thread https://github.com/notifications/unsubscribe-auth/AADBB81XsWGqkmDmVOAUmFwwro9UXm-Lks5tlIL0gaJpZM4TGXcb .
Thanks for the apt response. If /you/ have no idea how to generalize this, then I give up right here. Maybe a small note in the docs that this does not behave as one might expect from a map
function (it's more like an updateEach
) as "the monomorphic nature of the typeclasses disallows a more general approach" is all I can think of.
Feel free to close, I'm fine with the mapToList-mapFromList approach.
A PR for that doc update would be greatly appreciated!
On Wed, Apr 4, 2018 at 12:06 PM, Cies Breijs notifications@github.com wrote:
Thanks for the apt response. If /you/ have no idea how to generalize this, then I give up right here. Maybe a small note in the docs that this does not behave as one might expect from a map function (it's more like an updateEach) as "the monomorphic nature of the typeclasses disallows a more general approach" is all I can think of.
Feel free to close, I'm fine with the mapToList-mapFromList approach.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/snoyberg/mono-traversable/issues/162#issuecomment-378532620, or mute the thread https://github.com/notifications/unsubscribe-auth/AADBB0kZ3bjHUhlBRSq8pDivsD2UAgZ1ks5tlI0IgaJpZM4TGXcb .
I don't know if it is an appropriate solution, but PolyMap (being polymorphic) could have such a function if it had an associated key type:
type PolyMapKey map
pmapWithKey :: (PolyMapKey map -> v1 -> v2) -> map v1 -> map v2
Without it is also possible, but you would have to rely on SetContainer's ContainerKey:
pmapWithKey :: (SetContainer (map v1), SetContainer (map v2),
(ContainerKey (map v1)) ~ (ContainerKey (map v2)))
=> (ContainerKey (map v1) -> v1 -> v2)
-> map v1 -> map v2
Which seems a bit to restrictive to me, but it does work for all current instances of PolyMap.
This errors out:
And it seems obvious why:
Outputs:
So it can only map to exactly the same type of map. Very much what I'm not expecting from a
map
function in a higher-kinded language. Which would be:Allowing me (but obviously not forcing me) to change the type of map with mapping.
Is this restriction really needed? And, if yes, how do I get around it?
I'm now going the
mapToList
, processing, and then back withmapFromList
, route.I really like classy-prelude and all it brings me: thanks a lot for open source'ing and maintaining it!