sanctuary-js / sanctuary

:see_no_evil: Refuge from unsafe JavaScript
https://sanctuary.js.org
MIT License
3.03k stars 94 forks source link

Add `FoldableWithKey` and `TraversableWithKey` #614

Open masaeedu opened 5 years ago

masaeedu commented 5 years ago

It'd be handy to have something like foldMapWithKey so you can do:

const replaceAll = foldMapWithKey(Endo)(k => v => s => s.replace(k, v))

const f = replaceAll({
  "Earth": "Jupiter",
  "Mars": "Earth"
})

f("Come in Earth, this is Mars speaking")
// => "Come in Jupiter, this is Earth speaking"

Similarly traverseWithKey.

davidchambers commented 5 years ago

That looks neat, @masaeedu! What are the types of the two functions?

masaeedu commented 5 years ago

@davidchambers Weird, looks like I edited away the types I just edited in. Here they are:

type FoldableWithKey k f = {
  foldMapWithKey : Monoid m -> (k -> v -> m) -> f v -> m
}

and:

type TraversableWithKey k f = {
  traverseWithKey : Applicative f -> (k -> a -> f b) -> t a -> f (t b)
}
masaeedu commented 5 years ago

I'm actually still a little bit torn about whether it's a better idea to have foldMapWithKey and traverseWithKey or just: type WithKey k f = { withKey : f a -> f (k, a) }. If you do it the second way you can implement traverseWithKey just once for anything that happens to be both Traversable and WithKey (although of course you have to implement withKey for everything).