3 ms·
In Haskell you have appropriate typing for lenses because you build paths in a typed way. For instance, the API could like like this type Lens src tgt
by tel 12y ago
In Haskell you have appropriate typing for lenses because you build paths in a typed way. For instance, the API could like like this
type Lens src tgt
compose :: Lens src int -> Lens int tgt -> Lens src tgt
and then chains of lenses composed with `compose` would carry the appropriate typing information to not have to fall back on Any. This doesn't work "idiomatically" in Clojure because the *-in commands want to consume a list of keys where (1) each key is untyped and (2) the list cannot be heterogenous like it must be for the typed API.
That all said, it'd be easy to implement the typed API in Clojure as the "van Laarhoven" representation I mentioned has `Lens` just being a certain kind of function and `compose` just being regular (reversed) function composition: it's exactly like transducers in that regard (in fact, transducers can even be seen as a specific instance of a particular generalization of a lens, I believe).
The challenge is figuring out where the vtable for things like `map` lives. I'm pretty sure this is solvable in Clojure by using protocols (although I'm also pretty sure you can't get `Traverses` that way since you need return type polymorphism to get `pure` to work).
Anyway, it'd be neat to experiment. Maybe I'll teach myself some typed-clojure and see if I can't port the van Laarhoven lenses.
- kenko 12y ago> since you need return type polymorphism to get `pure` to work). If you don't mind an extra layer of interpretation (which you might very well mind!) you can get around this by building up basically an AST of your applicative computation---I did this, more or less, in my monads-in-clj library: https://github.com/bwo/monads https://github.com/bwo/monads which has a kind of not-that-useful applicative definition: https://github.com/bwo/monads https://github.com/bwo/monads I don't know too much about the innards of van Laarhoven lenses but I'd guess that a straight port might be inhibited by the fact that Clojure isn't pervasively lazy---so using Const as your functor, for instance, won't let you avoid actually computing the eventual second argument which is just discarded. But I dunno.
- tel 12y agoI was thinking about the applicative AST. I think that's a good solution, and perhaps if you're willing to explicitly compile it then you'll only need to pay once (and maybe even memoize it on later uses?) There shouldn't be a problem with strictness and van Laarhoven lenses. The particular trouble is just writing the lenses in the first place: (def one [inj] (fn [p] (fmap (fn [f] (pair f (snd p))) (inj (fst p))))) where did the `fmap` come from?