question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

define Array$prototype$bimap for two-element arrays

See original GitHub issue

@masaeedu shared this snippet in the Gitter room:

export const capitalizeKeys = o =>
  pipe([
    keys,
    map(k => ({ [k.toUpperCase()]: o[k] })),
    reduce(concat)({})
  ])(o);

After some discussion we agreed this code could be significantly nicer if S.pairs returned an array of honest-to-goodness pairs. One could then write:

//    capitalizeKeys :: StrMap a -> StrMap a
const capitalizeKeys = S.pipe ([S.pairs, S.map (S.mapLeft (S.toUpper)), S.fromPairs]);

This is not possible because ['foo', true] does not support bimap/mapLeft. It could do, but a problem arises when one considers map. How should S.map (S.toUpper) (['foo', 'bar']) evaluate? If one sees ['foo', 'bar'] as a member of Array String, the result should be ['FOO', 'BAR']. If, on the other hand, one sees ['foo', 'bar'] as a member of Pair String String, the result should be ['foo', 'BAR']. (Treating ['foo', true] as Pair String Boolean while treating ['foo', 'bar'] as Array String is out of the question.)

I’m reluctant to support bimap and mapLeft while leaving map out in the cold. I would rather not treat two-element arrays specially at all, and have functions such as S.pairs use the real Pair a b type soon to be released as sanctuary-pair.

@masaeedu posed an intriguing question:

Is mapRight not a thing?

It certainly could be a thing. It’s trivial to derive from bimap, as was the case with mapLeft. We could provide the following four functions:

map      ::   Functor f => (a -> b) -> f a -> f b
bimap    :: Bifunctor f => (a -> b) -> (c -> d) -> f a b -> f c d
mapLeft  :: Bifunctor f => (a -> b) -> f a c -> f b c
mapRight :: Bifunctor f => (b -> c) -> f a b -> f a c

mapRight would be equivalent to map for Either a b and various other types. For Pair a b, though, or Array2 a b as it will be known if sanctuary-js/sanctuary-def#182 is merged, mapRight would behave differently from map:

> S.map (S.toUpper) (['foo', 'bar'])
['FOO', 'BAR']

> S.mapRight (S.toUpper) (['foo', 'bar'])
['foo', 'BAR']

> S.mapRight (S.not) (['foo', true])
['foo', false]

I’d still like to consider having S.pairs return a real pair rather than a two-element array, but improving the usefulness of values such as ['foo', true] may be a good idea regardless. What do you think?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:3
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

4reactions
gabejohnsoncommented, Feb 15, 2018

The existence of bimap, mapLeft, and map mean many Pair a b transformations can be performed without lambdas, diminishing the importance of an inherent advantage of arrays: the ability to write ([k, v]) => …

Additionally, Pair implements the ECMAScript Iterable protocol so

(([x, y]) => x + y)(Pair(1, 2)) // 3

We can have our 🍰 and 🍴 it too 😄

1reaction
davidchamberscommented, Feb 15, 2018

sanctuary-type-classes should have no knowledge of Santuary’s type checking capabilities.

I agree. I was thinking that Array$prototype$bimap would do the length check itself and throw if this.length !== 2.

I think it’s going to be confusing in the long run to add a Bifunctor instance for arrays of any length and I suspect we’ll end up deciding to remove it in the future.

I appreciate your cautiousness. Let’s leave this issue open while pushing to release sanctuary-pair. The ergonomics of the real Pair a b type may prove to be excellent, in which case the value of treating two-element arrays as bifunctors would be greatly diminished. The existence of bimap, mapLeft, and map mean many Pair a b transformations can be performed without lambdas, diminishing the importance of an inherent advantage of arrays: the ability to write ([k, v]) => ....

Read more comments on GitHub >

github_iconTop Results From Across the Web

Array.prototype.map() - JavaScript - MDN Web Docs
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array....
Read more >
How To Use .map() to Iterate Through Array Items in JavaScript
.map() can be used to iterate through objects in an array and, in a similar fashion to traditional arrays, modify the content of...
Read more >
JavaScript Array.map() Tutorial – How to Iterate Through ...
Array.prototype.map() is a built-in array method for iterating through the elements inside an array collection in JavaScript. Think of looping ...
Read more >
Map over two arrays of objects, match properties and store ...
I am trying to map through two array of objects, and if a certain property matches, pull in specific information into an array....
Read more >
Deep Dive into JavaScript's Array Map Method - Robin Wieruch
entries does is it takes an object for its argument and spits out a two dimensional array (an array of arrays). Each item...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found