Lens: Finish the exercises based on Profunctors
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
This commit is contained in:
parent
7b37e979fe
commit
b1603f17ce
2 changed files with 52 additions and 59 deletions
107
src/Lets/Lens.hs
107
src/Lets/Lens.hs
|
@ -78,7 +78,7 @@ import Data.Char(toUpper)
|
||||||
import Data.Foldable(Foldable(foldMap))
|
import Data.Foldable(Foldable(foldMap))
|
||||||
import Data.Functor((<$>))
|
import Data.Functor((<$>))
|
||||||
import Data.Map(Map)
|
import Data.Map(Map)
|
||||||
import qualified Data.Map as Map(insert, delete, lookup)
|
import qualified Data.Map as Map(insert, delete, lookup, alterF)
|
||||||
import Data.Monoid(Monoid)
|
import Data.Monoid(Monoid)
|
||||||
import qualified Data.Set as Set(Set, insert, delete, member)
|
import qualified Data.Set as Set(Set, insert, delete, member)
|
||||||
import Data.Traversable(Traversable(traverse))
|
import Data.Traversable(Traversable(traverse))
|
||||||
|
@ -274,43 +274,39 @@ type Prism s t a b =
|
||||||
|
|
||||||
_Left ::
|
_Left ::
|
||||||
Prism (Either a x) (Either b x) a b
|
Prism (Either a x) (Either b x) a b
|
||||||
_Left = _
|
-- _Left h = let rh = right h in dimap (either Right (Left . Right)) (either pure (fmap Left)) rh
|
||||||
|
_Left h = let lh = left h in dimap (either Left (Right . Right)) (either (fmap Left) pure) lh
|
||||||
|
|
||||||
_Right ::
|
_Right ::
|
||||||
Prism (Either x a) (Either x b) a b
|
Prism (Either x a) (Either x b) a b
|
||||||
_Right =
|
_Right h = let rh = right h in dimap (either (Left . Left) Right) (either pure (fmap Right)) rh
|
||||||
error "todo: _Right"
|
|
||||||
|
|
||||||
prism ::
|
prism ::
|
||||||
(b -> t)
|
(b -> t)
|
||||||
-> (s -> Either t a)
|
-> (s -> Either t a)
|
||||||
-> Prism s t a b
|
-> Prism s t a b
|
||||||
prism =
|
prism bToT sToEta pafb = let rh = right pafb in dimap sToEta (either pure (fmap bToT)) rh
|
||||||
error "todo: prism"
|
|
||||||
|
|
||||||
_Just ::
|
_Just ::
|
||||||
Prism (Maybe a) (Maybe b) a b
|
Prism (Maybe a) (Maybe b) a b
|
||||||
_Just =
|
_Just = prism Just (maybe (Left Nothing) Right)
|
||||||
error "todo: _Just"
|
|
||||||
|
|
||||||
_Nothing ::
|
_Nothing ::
|
||||||
Prism (Maybe a) (Maybe a) () ()
|
Prism (Maybe a) (Maybe a) () ()
|
||||||
_Nothing =
|
_Nothing = prism (\_ -> Nothing) (maybe (Right ()) (Left . Just))
|
||||||
error "todo: _Nothing"
|
|
||||||
|
|
||||||
setP ::
|
setP ::
|
||||||
Prism s t a b
|
Prism s t a b
|
||||||
-> s
|
-> s
|
||||||
-> Either t a
|
-> Either t a
|
||||||
setP _ _ =
|
setP p = let pl = p Left in either Right Left . pl
|
||||||
error "todo: setP"
|
|
||||||
|
|
||||||
getP ::
|
getP ::
|
||||||
Prism s t a b
|
Prism s t a b
|
||||||
-> b
|
-> b
|
||||||
-> t
|
-> t
|
||||||
getP _ _ =
|
-- Copied :(
|
||||||
error "todo: getP"
|
getP p = let pti = p . Tagged . Identity in getIdentity . getTagged . pti
|
||||||
|
|
||||||
type Prism' a b =
|
type Prism' a b =
|
||||||
Prism a a b b
|
Prism a a b b
|
||||||
|
@ -333,8 +329,7 @@ modify ::
|
||||||
-> (a -> b)
|
-> (a -> b)
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
modify _ _ _ =
|
modify l f = getIdentity . l (Identity . f)
|
||||||
error "todo: modify"
|
|
||||||
|
|
||||||
-- | An alias for @modify@.
|
-- | An alias for @modify@.
|
||||||
(%~) ::
|
(%~) ::
|
||||||
|
@ -363,8 +358,7 @@ infixr 4 %~
|
||||||
-> b
|
-> b
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
(.~) _ _ _ =
|
(.~) l = let ml = modify l in ml . const
|
||||||
error "todo: (.~)"
|
|
||||||
|
|
||||||
infixl 5 .~
|
infixl 5 .~
|
||||||
|
|
||||||
|
@ -384,8 +378,7 @@ fmodify ::
|
||||||
-> (a -> f b)
|
-> (a -> f b)
|
||||||
-> s
|
-> s
|
||||||
-> f t
|
-> f t
|
||||||
fmodify _ _ _ =
|
fmodify l = l
|
||||||
error "todo: fmodify"
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -400,8 +393,7 @@ fmodify _ _ _ =
|
||||||
-> f b
|
-> f b
|
||||||
-> s
|
-> s
|
||||||
-> f t
|
-> f t
|
||||||
(|=) _ _ _ =
|
(|=) l = let fl = fmodify l in fl . const
|
||||||
error "todo: (|=)"
|
|
||||||
|
|
||||||
infixl 5 |=
|
infixl 5 |=
|
||||||
|
|
||||||
|
@ -411,8 +403,7 @@ infixl 5 |=
|
||||||
-- (30,"abc")
|
-- (30,"abc")
|
||||||
fstL ::
|
fstL ::
|
||||||
Lens (a, x) (b, x) a b
|
Lens (a, x) (b, x) a b
|
||||||
fstL =
|
fstL f (x, y) = let fx = f x in fmap (\x' -> (x', y)) fx
|
||||||
error "todo: fstL"
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -420,8 +411,7 @@ fstL =
|
||||||
-- (13,"abcdef")
|
-- (13,"abcdef")
|
||||||
sndL ::
|
sndL ::
|
||||||
Lens (x, a) (x, b) a b
|
Lens (x, a) (x, b) a b
|
||||||
sndL =
|
sndL f (x, y) = let fy = f y in fmap (\y' -> (x, y')) fy
|
||||||
error "todo: sndL"
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -496,8 +486,7 @@ compose ::
|
||||||
Lens s t a b
|
Lens s t a b
|
||||||
-> Lens q r s t
|
-> Lens q r s t
|
||||||
-> Lens q r a b
|
-> Lens q r a b
|
||||||
compose _ _ =
|
compose l1 l2 = l2 . l1
|
||||||
error "todo: compose"
|
|
||||||
|
|
||||||
-- | An alias for @compose@.
|
-- | An alias for @compose@.
|
||||||
(|.) ::
|
(|.) ::
|
||||||
|
@ -518,8 +507,7 @@ infixr 9 |.
|
||||||
-- 4
|
-- 4
|
||||||
identity ::
|
identity ::
|
||||||
Lens a b a b
|
Lens a b a b
|
||||||
identity =
|
identity = id
|
||||||
error "todo: identity"
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -562,8 +550,9 @@ choice ::
|
||||||
Lens s t a b
|
Lens s t a b
|
||||||
-> Lens q r a b
|
-> Lens q r a b
|
||||||
-> Lens (Either s q) (Either t r) a b
|
-> Lens (Either s q) (Either t r) a b
|
||||||
choice _ _ =
|
choice l1 l2 = (\f esq -> case esq of
|
||||||
error "todo: choice"
|
Left s -> Left <$> (l1 f s)
|
||||||
|
Right q -> Right <$> (l2 f q))
|
||||||
|
|
||||||
-- | An alias for @choice@.
|
-- | An alias for @choice@.
|
||||||
(|||) ::
|
(|||) ::
|
||||||
|
@ -646,8 +635,7 @@ intAndL p (IntAnd n a) =
|
||||||
getSuburb ::
|
getSuburb ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
getSuburb =
|
getSuburb = get $ (compose suburbL addressL)
|
||||||
error "todo: getSuburb"
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -660,8 +648,7 @@ setStreet ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
-> Person
|
-> Person
|
||||||
setStreet =
|
setStreet = set $ (compose streetL addressL)
|
||||||
error "todo: setStreet"
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -673,8 +660,8 @@ setStreet =
|
||||||
getAgeAndCountry ::
|
getAgeAndCountry ::
|
||||||
(Person, Locality)
|
(Person, Locality)
|
||||||
-> (Int, String)
|
-> (Int, String)
|
||||||
getAgeAndCountry =
|
getAgeAndCountry (person, locality) = (get ageL person,
|
||||||
error "todo: getAgeAndCountry"
|
get countryL locality)
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -685,8 +672,9 @@ getAgeAndCountry =
|
||||||
-- (Person 28 "Mary" (Address "83 Mary Ln" "Maryland" (Locality "Some Other City" "Western Mary" "Maristan")),Address "15 Fred St" "Fredville" (Locality "Mary Mary" "Western Mary" "Maristan"))
|
-- (Person 28 "Mary" (Address "83 Mary Ln" "Maryland" (Locality "Some Other City" "Western Mary" "Maristan")),Address "15 Fred St" "Fredville" (Locality "Mary Mary" "Western Mary" "Maristan"))
|
||||||
setCityAndLocality ::
|
setCityAndLocality ::
|
||||||
(Person, Address) -> (String, Locality) -> (Person, Address)
|
(Person, Address) -> (String, Locality) -> (Person, Address)
|
||||||
setCityAndLocality =
|
setCityAndLocality (person, address) (city, locality) =
|
||||||
error "todo: setCityAndLocality"
|
(set (cityL |. localityL |. addressL) person city,
|
||||||
|
set localityL address locality)
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -699,7 +687,7 @@ getSuburbOrCity ::
|
||||||
Either Address Locality
|
Either Address Locality
|
||||||
-> String
|
-> String
|
||||||
getSuburbOrCity =
|
getSuburbOrCity =
|
||||||
error "todo: getSuburbOrCity"
|
get (suburbL ||| cityL)
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -713,7 +701,7 @@ setStreetOrState ::
|
||||||
-> String
|
-> String
|
||||||
-> Either Person Locality
|
-> Either Person Locality
|
||||||
setStreetOrState =
|
setStreetOrState =
|
||||||
error "todo: setStreetOrState"
|
set (streetL |. addressL ||| stateL)
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -726,22 +714,20 @@ modifyCityUppercase ::
|
||||||
Person
|
Person
|
||||||
-> Person
|
-> Person
|
||||||
modifyCityUppercase =
|
modifyCityUppercase =
|
||||||
error "todo: modifyCityUppercase"
|
cityL |. localityL |. addressL %~ map toUpper
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >>> modifyIntAndLengthEven (IntAnd 10 "abc")
|
-- >>> modify intAndL (even . length) (IntAnd 10 "abc")
|
||||||
-- IntAnd 10 False
|
-- IntAnd 10 False
|
||||||
--
|
--
|
||||||
-- >>> modifyIntAndLengthEven (IntAnd 10 "abcd")
|
-- >>> modify intAndL (even . length) (IntAnd 10 "abcd")
|
||||||
-- IntAnd 10 True
|
-- IntAnd 10 True
|
||||||
modifyIntAndLengthEven ::
|
modifyIntAndLengthEven ::
|
||||||
IntAnd [a]
|
IntAnd [a]
|
||||||
-> IntAnd Bool
|
-> IntAnd Bool
|
||||||
modifyIntAndLengthEven =
|
modifyIntAndLengthEven =
|
||||||
error "todo: modifyIntAndLengthEven"
|
intAndL %~ even . length
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -749,8 +735,8 @@ modifyIntAndLengthEven =
|
||||||
-- Locality "ABC" "DEF" "GHI"
|
-- Locality "ABC" "DEF" "GHI"
|
||||||
traverseLocality ::
|
traverseLocality ::
|
||||||
Traversal' Locality String
|
Traversal' Locality String
|
||||||
traverseLocality =
|
traverseLocality f (Locality c t y) =
|
||||||
error "todo: traverseLocality"
|
Locality <$> f c <*> f t <*> f y
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -762,25 +748,32 @@ traverseLocality =
|
||||||
intOrIntP ::
|
intOrIntP ::
|
||||||
Prism' (IntOr a) Int
|
Prism' (IntOr a) Int
|
||||||
intOrIntP =
|
intOrIntP =
|
||||||
error "todo: intOrIntP"
|
prism
|
||||||
|
IntOrIs
|
||||||
|
(\i -> case i of
|
||||||
|
IntOrIs n -> Right n
|
||||||
|
IntOrIsNot a -> Left (IntOrIsNot a))
|
||||||
|
|
||||||
intOrP ::
|
intOrP ::
|
||||||
Prism (IntOr a) (IntOr b) a b
|
Prism (IntOr a) (IntOr b) a b
|
||||||
intOrP =
|
intOrP =
|
||||||
error "todo: intOrP"
|
prism
|
||||||
|
IntOrIsNot
|
||||||
|
(\i -> case i of
|
||||||
|
IntOrIs n -> Left (IntOrIs n)
|
||||||
|
IntOrIsNot a -> Right a)
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >> intOrLengthEven (IntOrIsNot "abc")
|
-- >> over intOrP (even . length) (IntOrIsNot "abc")
|
||||||
-- IntOrIsNot False
|
-- IntOrIsNot False
|
||||||
--
|
--
|
||||||
-- >>> intOrLengthEven (IntOrIsNot "abcd")
|
-- >>> over intOrP (even . length) (IntOrIsNot "abcd")
|
||||||
-- IntOrIsNot True
|
-- IntOrIsNot True
|
||||||
--
|
--
|
||||||
-- >>> intOrLengthEven (IntOrIs 10)
|
-- >>> over intOrP (even . length) (IntOrIs 10)
|
||||||
-- IntOrIs 10
|
-- IntOrIs 10
|
||||||
intOrLengthEven ::
|
intOrLengthEven ::
|
||||||
IntOr [a]
|
IntOr [a]
|
||||||
-> IntOr Bool
|
-> IntOr Bool
|
||||||
intOrLengthEven =
|
intOrLengthEven = over intOrP (even . length)
|
||||||
error "todo: intOrLengthEven"
|
|
||||||
|
|
|
@ -64,12 +64,12 @@ data Lens s t a b =
|
||||||
Lens
|
Lens
|
||||||
(forall f. Functor f => (a -> f b) -> s -> f t)
|
(forall f. Functor f => (a -> f b) -> s -> f t)
|
||||||
|
|
||||||
|
-- Const :: forall b . a -> Const a b
|
||||||
get ::
|
get ::
|
||||||
Lens s t a b
|
Lens s t a b
|
||||||
-> s
|
-> s
|
||||||
-> a
|
-> a
|
||||||
get (Lens r) =
|
get (Lens r) s = let rc = r Const in getConst $ rc s
|
||||||
getConst . r Const
|
|
||||||
|
|
||||||
set ::
|
set ::
|
||||||
Lens s t a b
|
Lens s t a b
|
||||||
|
|
Loading…
Reference in a new issue