0

I want to do what I think is the simplest thing, map through a plain old Javascript object, using fp-ts constructs.

There are a lot of operators I would like to use — map, filterMap, and so on — but they seem to require the Map type (which I assume is the Javascript Map object) — and there does not seem to be any easy way to convert back and forth between Map and Javascript object, which in Typescript is the standard representation of algebraic data types and of its Record<K,V> type.

This seems like a pretty big hole. Please don’t tell me I have to switch to lodash...

Michael Lorton
  • 43,060
  • 26
  • 103
  • 144
  • I don't know fp-ts, however "mapping an object" should mean "I execute a function with the object as parameter". So, I'd expect `map(f, obj)` to be basically the same as `f(obj)`. With this in mind, you could use a functor for the object which would allow you to call `map` on it. Again, I don't know fp-ts but it should have an identity functor under some name. – VLAZ Feb 13 '22 at 08:34
  • @VLAZ — the issue isn’t the name; fp-ts has several functors that do the things I want done; it just does them to types other than `object`. There is a `map` for List and for Map, just none for objects. – Michael Lorton Feb 13 '22 at 15:46
  • Wait, when you say you want to map objects, what do you mean? You want to transform *one whole object* or you want to transform *each value of an object*? – VLAZ Feb 13 '22 at 15:50
  • @VLAZ — different things, but for example, I would like `map(v => v+1)({a: 6})` to compile (which it does not do now) and yield `{a: 7}`. `map(v => v+1)(new Map([['a', 6]]))` does work and does yield `Map([['a', 7]])` but is not what I want. Ps. Why does Javascript have a concept called `map` and another called `Map` and they are almost totally different? How about “AssociativeArray” or “Dictionary”? – Michael Lorton Feb 13 '22 at 16:28
  • Both terms come from other places and relate to the same concept. But in different ways. A Map defines a data structure that associates keys with values. Java also calls this a Map. But some languages do call it other things like C# has a Dictionary but it's exactly the same concept. JS is neither the first, nor would be the last language that uses this term. While [`.map()` defines an association of an item with another item via a function](https://en.wikipedia.org/wiki/Map_(higher-order_function)). You can think of capital M Map is a noun, while lowercase m map is a verb. One is a – VLAZ Feb 13 '22 at 16:50
  • static lookup, the other dynamically computes the product but in both cases you "put something in" and you "get something out" and the input and output are related. As for *why* capital M Map was chosen for a name - you'd have to ask the members of TC39. I don't know the rationale. IMO it would have made more sense to call it something else, to not confuse the terms. Java does have an excuse, since it had Map but introduced `.map()` later and it's quite hard to call it something different, it's a pretty standard name in FP. – VLAZ Feb 13 '22 at 16:50
  • @VLAZ — I understood the thought process; what I don’t understand is the absence of the countervailing thought process wherein they reason, “Hey, if we call both things ‘map’, a lot of conversations become a lot more difficult. There are lots of other names; let’s use one of them.” Just to twist the knife, for Promises they renamed both `map()` and `flatMap()` to `then()`. *Cf.* chain, bind, of, point, return, and whatever `>>=` is supposed to be. As Updike asked about God and women: “A mistake? Or did He do it to us on purpose?” – Michael Lorton Feb 13 '22 at 17:51
  • Promises do not satisfy the monadic laws, so they aren't actually monads. If a function returns an object with a `then` method (a "thenable"), then it gets automatically converted into a promise itself. Which then violates the left identity law when a function `f` returns a thenable. It also violates the associativity law when you have `p.then(f).then(g)` and both functions don't return a promise but a thenable. All this to say that promises having a `.then` over a monadic `.chain` does make sense. However, again why capital M Map was chosen - I do not know. I'd prefer it wasn't. – VLAZ Feb 13 '22 at 19:10

1 Answers1

3

fp-ts/Record lets you work with Record<K, V> as if they were a Functor in V, so you can have

import { map } from 'fp-ts/Record'

const mapped = map((v: number) => v + 1)({a: 1}) // { a: 2 }
bugs
  • 14,631
  • 5
  • 48
  • 52