Lens: Finish the exercises based on Profunctors

Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
This commit is contained in:
Sanchayan Maity 2020-03-21 11:47:40 +05:30
parent 7b37e979fe
commit b1603f17ce
2 changed files with 52 additions and 59 deletions

View file

@ -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"

View file

@ -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