diff --git a/introlenses/introlenses.html b/introlenses/introlenses.html
index b861373..d4f4860 100644
--- a/introlenses/introlenses.html
+++ b/introlenses/introlenses.html
@@ -295,7 +295,7 @@
Same again... using a lens to view
view :: Lens' s a -> s -> a
view ln s = getConst (ln Const s)
-Here Const is, deduced by the type inferencer, a -> Const a a
+Here Const is a -> Const a a
(which is deduced by the type system)
Or, as Edward would write it:
view :: Lens' s a -> s -> a
@@ -316,9 +316,7 @@ From Lens to LensR
lensToLensR :: Lens' s a -> LensR s a
LensToLensR ln = L { viewR = view ln, setR = set ln }
-
-
-
Exercise
+
Exercise
@@ -339,19 +337,17 @@
Let's create a Lens
name elt_fn (
P n s)
= fmap (\n'
-> P n' s) (elt_fn n)
-- elt_fn
-- String -> f String
-element function
-- ' -> P n' s
-- String -> Person
+elt_fn :: String -> f String
+
+(\n' -> P n' s) :: String -> Person
+
- It's like a data structure with a hole in it
-It's the function that replaces the name of the given Person
-- elt_fn n
-f String
-fmap is needed to go from f String to f Person given String -> Person
-I can express it using <$> from Data.Functor
+- It's the function that replaces the name of the given Person
+
+(elt_fn n) :: f String
-name elt_fn (P n s) = (\n' -> P n' s) <$> (elt_fn n)
Using lens
@@ -376,7 +372,7 @@ How on earth does this work?
= "Fred"
The newtype has no runtime cost
-I just tell the "Functor f =>" which functor dictionary to pass to ln
+I just tell the "Functor f =>
" which functor dictionary to pass to ln
The place where the fmap threw away the function was precisely where the wrapper (the reconstruction function) got discarded giving only the value to return.
@@ -404,7 +400,7 @@ Composing and using lenses
ln1 . ln2 :: (a -> f a) -> s1 -> f s1
-- So lens composition is simply function composition, namely (.)
+- So lens composition is simply function composition, namely
(.)
!!!!
@@ -548,8 +544,8 @@
Fumbling in deep data structures
Traversals
type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
-We have seen that can instantiate 'f' in various ways
-But what if we changed "Functor" ?
+We have seen that can instantiate f
in various ways
+But what if we changed Functor
?
type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s
@@ -564,13 +560,13 @@ What on earth is Applicative?
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
-- A bit like Monad, but weaker
+- A bit like
Monad
, but weaker
class Applicative f => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
-- Every Monad is an Applicative
+- Every
Monad
is an Applicative
pure = return
mf <*> mx = do { f <- mf; x <- mx; return (f x)}
@@ -614,34 +610,33 @@ Using Traversals
over :: Lens' s a => (a -> a) -> s -> s
over ln f = runIdentity . ln (Identify . f)
-- Imagine instead ln :: Traversal' s a, does that work?
+- Imagine instead
ln :: Traversal' s a
, does that work?
over :: Traversal' s a -> (a -> a) -> s -> s
over ln f = runIdentity . ln (Identity . f)
-Yes, if Identity is an instance of Applicative, which it is.
-over in action
+Yes, if Identity
is an instance of Applicative
(which it is)
+over
in action
ghci> let fredA = A "71 Humberstone Rd" "Cambridge" "CB4 1JD"
ghci> over addr_strs toLower fredA
A "71 humberstone rd" "cambridge" "CB4 1JD"
-
-
...more plase... try 'view'
+
+
...more please... try 'view'
view :: Lens' s a -> s -> a
view ln s = getConst (ln Const s)
-- Try replacing Lens with Traversal
+- Try replacing
Lens
with Traversal
view :: Traversal' s a -> s -> a
view ln s = getConst (ln Const s)
-This absolutely can't work! (Why not?)
-We need Const to be an instance of Applicative
+This absolutely can't work!
+
+- We need
Const
to be an instance of Applicative
+
-
class Functor f => Applicative f where
- pure :: a -> f a
- (<*>) :: f (a -> b) -> f a -> f b
newtype Const v a = Const v
getConst :: Const v a -> v
@@ -654,8 +649,11 @@ ...more plase... try 'view'
instance Monoid a => Applicative (Const a) where
pure x = Const mempty
(Const vf) <*> (Const va) = Const (vp `mappend` va)
+
+
+
View on Traversals
-- So 'view' on Traversals does a kind of fold
+- So
view
on Traversals
does a kind of fold
instance Monoid [a] where
mempty = []
@@ -663,11 +661,9 @@ ...more plase... try 'view'
ghci> let fredA = A "71 Humberstone Rd" "Cambridge" "CB4 1JD"
ghci> view addr_strs fredA
"71 Humberstone RdCambridge"
-
-
Composing Traversals
+
+- Traversals and Lenses compose !!!
+
type Lens' s a = forall f. Functor f
=> (a -> f a) -> s -> f s
type Traversal' s a = forall f. Applicative f
@@ -700,7 +699,8 @@ Unusually for a library, lenses are not abstract
=> (a -> f a) -> s -> f s)
Lenses and traversals would not compose (or would require lots of different functions to do so)
-BUT: the inner workings are more exposed
+The inner workings are more exposed
+But you don't need the lenses library to create lenses (they're only rank-2 functions !!!)
@@ -712,7 +712,8 @@
I have been lying throughout
type Lens s t a b
= forall f. Functor f => (a -> f b) -> s -> f t
-
-- over :: Lens' s a -> (a -> a) -> s -> s > over :: Profunctor p => Setting p s t a b -> p a b -> s -> t
+
-- over :: Lens' s a -> (a -> a) -> s -> s
+over :: Profunctor p => Setting p s t a b -> p a b -> s -> t
Take away thoughts
A hymn to the power of abstraction
-Lenses, and their variants (notabli Traversals), as a composable first-class values, giver remarkable expressive power
-- It all rests on Haskell's abstraction facilities:
+Lenses, and their variants (notably Traversals), as a composable first-class values, giver remarkable expressive power
+- It all rests on Haskell's abstraction facilities:
+