DrBoolean / lenses

Composable kmett style lenses
214 stars 13 forks source link

Explanation #7

Open ccorcos opened 9 years ago

ccorcos commented 9 years ago

Hey dude, I saw this and wanted to better understand how lenses work. The code was pretty confusing to me, so I thought I'd start with what does this mean?

/*
* type Lens s t a b = ∀f. Functor f => (a -> f b) -> s -> f t
* type Setter s t a b = (a -> Identity b) -> s -> Identity t
* type Getting r s t a b = (a -> Const r b) -> s -> Const r t
* type Getter s a = ∀r. (a -> Const r a) -> s -> Const r s
* type Traversal s t a b = ∀f. Applicative f => (a -> f b) -> s -> f t
* type Fold s a = ∀m. Monoid m => (a -> Const m a) -> s -> Const m s
*/

I have a math background so I understand for-all. But other than that, I'm lost. Any online books or classes you'd recommend?

DrBoolean commented 9 years ago

Hi! I ported the types from this lib/video https://www.youtube.com/watch?v=cefnmjtAolY from edward kmett. I feel like the video is a much better explanation that i could try to type :)

ccorcos commented 9 years ago

Oy. I'm lost from the very beginning... I don't know Haskell or this notation. Where should I start?

vendethiel commented 9 years ago

I think this could be a good start. it has lots of ressources. It's a pretty big amount of time to invest, though.

DrBoolean commented 9 years ago

He did the same presentation in scala if that's more familiar. Are you good with functors already? I'd start tbere

ccorcos commented 9 years ago

I'm pretty much just familiar with JS and Python... I get functors.

mLuby commented 9 years ago

@ccorcos the syntax definitely takes some getting used to. Here's how I interpret it: type Fold s a = ∀m. Monoid m => (a -> Const m a) -> s -> Const m s means type Fold "I'm defining Fold to be of the type" s a = "that takes an s and an a" ∀m. Monoid m => "such that for all Monoids m*" (a -> Const m a) -> "given a function taking an a and returning a Const a m" s -> "and given an s" Const m s "Fold will return a Const m s."

* not sure this interpretation is accurate enough.

ccorcos commented 9 years ago

interesting. that makes sense. the periods we're throwing me off in terms of how it flows. Its also interesting how its all automatically curried in some sense.

ccorcos commented 9 years ago

So you can read these sentences and understand whats going on without thinking about it for 10 minutes?

Lens s t a b = ∀f. Functor f => (a -> f b) -> s -> f t

I'm not sure this makes much sense to me.

For any functor, a lens takes a function (a -> f b) and an s and return f t. This is meaningless to me. How do I interpret what this function will actually do for me?

LiamGoodacre commented 9 years ago

Start with the simpler version:

Lens' s a = Lens s s a a

or

Lens' s a = ∀f. Functor f => (a -> f a) -> s -> f s

With the example of a Person with a Name: Lens' Person Name.

Which could be read as:

With the use of a Lens, functions will select a specific f to use based on what they want to achieve.

If f = Const Name then we have: (Name -> Const Name Name) -> Person -> Const Name Person. This the lets you extract the Name from a Person - related to the function view.

If f = Identity then we have: (Name -> Identity Name) -> Person -> Identity Person. Which essentially gives you "modify a person's name by some function" - related to the function over.

The full version of Lens adds to this the ability to change types. For example: Lens (l, r) (l, n) r n says we if we can convert an r into an n, then we can transform a pair (l, r) into (l, n).

Does that make sense?

ccorcos commented 9 years ago

hmm. I think what confuses me is there's no distriction between multiple inputs, multiple outputs, and applying a functor to some arguments.

Lens'  (s, a) = ∀f. Functor f => (a -> f(a)) -> s -> f(s)

Is that the right idea? that f isnt being returned but transforming the arugments? that doesnt seem quite right though.