Evaluations
Johan Kiviniemi edited this page Dec 26, 2012
·
6 revisions
Pages 16
Clone this wiki locally
Manual Evaluations
This page contains manual evaluations of various interesting function calls to demonstrate what is going on in the internals of Lens.
Note 1: Some functions have been simplified by making them less generic or shorter-but-less-efficient than the actual versions in Lens for pedagogical reasons. See the Lens source code for the actual implementations.
-
Const
≡Accessor
-
Identity
≡Mutator
Lens
both . both
(Based on pre-3.8, 2012-12-26)
both . both
-- both f (x,y) = (,) <$> f x <*> f y
both . (\f (x,y) -> (,) <$> f x <*> f y)
\f -> both (\(x,y) -> (,) <$> f x <*> f y)
\f -> (\g (ab,cd) -> (,) <$> g ab <*> g cd) (\(x,y) -> (,) <$> f x <*> f y)
\f -> \(ab,cd) -> (,) <$> (\(a,b) -> (,) <$> f a <*> f b) ab
<*> (\(c,d) -> (,) <$> f c <*> f d) cd
\f ((a,b),(c,d)) -> (,) <$> ((,) <$> f a <*> f b)
<*> ((,) <$> f c <*> f d)
Iso
view (iso (*10) (/10)) 5
(Based on pre-3.8, 2012-12-26)
view (iso (*10) (/10)) 5
-- view l = getConst . l Const -- (See note 1)
getConst $ iso (*10) (/10) Const 5
-- iso sa bt = lmap sa . rmap (fmap bt)
getConst $ (lmap (*10) . rmap (fmap (/10))) Const 5
getConst $ lmap (*10) (rmap (fmap (/10)) Const) 5
-- lmap f sa = sa . f
-- rmap f bt = f . bt
getConst $ (fmap (/10) . Const . (*10)) 5
(*10) 5
over (iso (*10) (/10)) (+1) 5
(Based on pre-3.8, 2012-12-26)
over (iso (*10) (/10)) (+1) 5
-- over l f = runIdentity . l (Identity . f)
runIdentity $ iso (*10) (/10) (Identity . (+1)) 5
-- iso sa bt = lmap sa . rmap (fmap bt)
runIdentity $ (lmap (*10) . rmap (fmap (/10))) (Identity . (+1)) 5
runIdentity $ lmap (*10) (rmap (fmap (/10)) (Identity . (+1))) 5
-- lmap f sa = sa . f
-- rmap f bt = f . bt
runIdentity $ (fmap (/10) . Identity . (+1) . (*10)) 5
(/10) . (+1) . (*10) $ 5
from (iso (*10) (/10))
(Based on pre-3.8, 2012-12-26)
from (iso (*10) (/10))
-- from k = case runIso k of (sa, bt) -> iso bt sa
case runIso (iso (*10) (/10)) of
(sa, bt) -> iso bt sa
-- newtype Exchange a b s t = Exchange { runExchange :: (s -> a, b -> t) }
-- runIso ai = case runExchange (ai (Exchange (id, Identity))) of
-- (sa, bt) -> (sa, runIdentity . bt)
case runExchange (iso (*10) (/10) (Exchange (id, Identity))) of
(sa, bt) -> iso (runIdentity . bt) sa
-- iso sa bt = lmap sa . rmap (fmap bt)
case runExchange ((lmap (*10) . rmap (fmap (/10))) (Exchange (id, Identity))) of
(sa, bt) -> iso (runIdentity . bt) sa
case runExchange (lmap (*10) (rmap (fmap (/10)) (Exchange (id, Identity)))) of
(sa, bt) -> iso (runIdentity . bt) sa
-- rmap f (Exchange (sa, bt)) = Exchange (sa, f . bt)
case runExchange (lmap (*10) (Exchange (id, fmap (/10) . Identity))) of
(sa, bt) -> iso (runIdentity . bt) sa
-- lmap f (Exchange (sa, bt)) = Exchange (sa . f, bt)
case runExchange (Exchange (id . (*10), fmap (/10) . Identity)) of
(sa, bt) -> iso (runIdentity . bt) sa
case (id . (*10), fmap (/10) . Identity) of
(sa, bt) -> iso (runIdentity . bt) sa
iso (runIdentity . fmap (/10) . Identity) (id . (*10))
iso (/10) (*10)
Bazaar
both sell ("foo","bar")
(Based on pre-3.8, 2012-12-26)
both sell ("foo","bar")
-- both f (a,b) = (,) <$> f a <*> f b
(\f -> (,) <$> f "foo" <*> f "bar") sell
(,) <$> sell "foo" <*> sell "bar"
-- sell a = Bazaar (\f -> f a) -- (See note 1)
(,) <$> Bazaar (\f -> f "foo") <*> Bazaar (\f -> f "bar")
-- fmap f (Bazaar k) = Bazaar (fmap f . k)
Bazaar (fmap (,) . (\f -> f "foo")) <*> Bazaar (\f -> f "bar")
Bazaar (\f -> (,) <$> f "foo") <*> Bazaar (\f -> f "bar")
-- Bazaar mf <*> Bazaar ma = Bazaar $ \k -> mf k <*> ma k
Bazaar (\f -> (,) <$> f "foo" <*> f "bar")
Bazaar (\f -> both f ("foo","bar"))
partsOf' (both . both)
See above for evaluations of both . both
and l sell s
.
(Based on pre-3.8, 2012-12-26)
partsOf' (both . both) f ((3,4),(5,6))
-- partsOf' l f s = outs b <$> f (ins b) where b = l sell s
let b = (both . both) sell ((3,4),(5,6))
in outs b <$> f (ins b)
-- l sell s = Bazaar $ \g -> l g s
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
in outs b <$> f (ins b)
-- ins = toListOf (flip runBazaar)
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
inned = toListOf (flip runBazaar) b
in outs b <$> f inned
-- toListOf l = getConst . l (\x -> Const [x]) -- (See note 1)
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
inned = getConst $ flip runBazaar (\x -> Const [x]) b
in outs b <$> f inned
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
inned = getConst $ runBazaar b (\x -> Const [x])
in outs b <$> f inned
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
inned = getConst $ (,) <$> ((,) <$> Const [3] <*> Const [4])
<*> ((,) <$> Const [5] <*> Const [6])
in outs b <$> f inned
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
inned = [3,4,5,6]
in outs b <$> f inned
let b = Bazaar $ \g -> (both . both) g ((3,4),(5,6))
outed = evalState (runBazaar b st)
st _oldX = state (\(x:xs) -> (x, xs))
in outed <$> f [3,4,5,6]
let outed = evalState $ (,) <$> ((,) <$> st 3 <*> st 4)
<*> ((,) <$> st 5 <*> st 6)
st _oldX = state (\(x:xs) -> (x,xs))
in outed <$> f [3,4,5,6]
view (partsOf' (both . both)) ((3,4),(5,6))
getConst $ outed <$> Const [3,4,5,6]
[3,4,5,6]
-- Better: over (partsOf' (both . both) . mapped) (*10) ((3,4),(5,6))
over (partsOf' (both . both)) (map (*10)) ((3,4),(5,6))
runIdentity $ outed <$> (Identity . map (*10)) [3,4,5,6]
((30,40),(50,60))