given that map
is:
map :: (a -> b) -> [a] -> [b]
why R.map(R.toUpper, 'hello')
returns ['H', 'E', 'L', 'L', 'O']
and not "HELLO"
?
in haskell, for instance, a string is a list of chars, so map toUpper "hello"
behaves as expected (HELLO
).
Shouldn't Ramda's map
be doing the same?
It might be a design choice but I think Ramda's map might be violating the functor law: If we map the id function over a functor, we don't get back the original functor
console.log(
R.map(R.identity, 'Hello World'),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>
Why wouldn't I be expecting map
to behave more like:
const map = (fn, string) => string.replace(/./g, fn);
console.log(
map(R.toUpper, 'hello world'),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>
As the comments say, Strings are not functor
s. The functor laws require
map :: Functor f => (a -> b) -> f a -> f b
That is, for a functor holding an item or items of type a
and a function from type a
to type b
, it will return a functor of the same type holding an item or items of type b
. A String cannot do that, as it holds only characters. For instance, what would you expect map(_ => 1.234, "hello")
to return?
Ramda's behavior on Strings is not intentional. It simply falls out of the implementation, as Bergi suggested. Strings look enough like arrays (with integer length
properties and integer-indexed sub-elements) that the code treats them as though they were arrays.
Ramda has always intended to be a low-level library, and the founders weren't particularly interested in writing hand-holding code. It should work as advertised if you supply the types required, but there are few guarantees if you don't. However, if you feel strongly about this, feel free to raise an issue with the Ramda team about it, or even better, raise a pull request with the behavior you'd prefer. It might not get accepted, but it will receive a fair hearing.