Compare commits
No commits in common. "lens_practice" and "master" have entirely different histories.
lens_pract
...
master
6 changed files with 220 additions and 301 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -30,7 +30,3 @@ TAGS
|
||||||
|
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
# STACK
|
|
||||||
.stack-work
|
|
||||||
stack.yaml.lock
|
|
||||||
tags
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import Data.Char(toUpper)
|
||||||
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)
|
||||||
import Data.Set(Set)
|
import Data.Set(Set)
|
||||||
import qualified Data.Set as Set(insert, delete, member, fromList)
|
import qualified Data.Set as Set(insert, delete, member)
|
||||||
import Lets.Data(Person(Person), Locality(Locality), Address(Address))
|
import Lets.Data(Person(Person), Locality(Locality), Address(Address))
|
||||||
import Prelude hiding (product)
|
import Prelude hiding (product)
|
||||||
|
|
||||||
|
@ -144,7 +144,8 @@ modify ::
|
||||||
-> (b -> b)
|
-> (b -> b)
|
||||||
-> a
|
-> a
|
||||||
-> a
|
-> a
|
||||||
modify = \(Lens f g) -> \bTob -> \a -> f a (bTob (g a))
|
modify =
|
||||||
|
error "todo: modify"
|
||||||
|
|
||||||
-- | An alias for @modify@.
|
-- | An alias for @modify@.
|
||||||
(%~) ::
|
(%~) ::
|
||||||
|
@ -173,7 +174,8 @@ infixr 4 %~
|
||||||
-> b
|
-> b
|
||||||
-> a
|
-> a
|
||||||
-> a
|
-> a
|
||||||
(.~) = \(Lens f _) -> \b -> \a -> f a b
|
(.~) =
|
||||||
|
error "todo: (.~)"
|
||||||
|
|
||||||
infixl 5 .~
|
infixl 5 .~
|
||||||
|
|
||||||
|
@ -193,7 +195,8 @@ fmodify ::
|
||||||
-> (b -> f b)
|
-> (b -> f b)
|
||||||
-> a
|
-> a
|
||||||
-> f a
|
-> f a
|
||||||
fmodify = \(Lens f g) -> \bTofb -> \a -> (f a) <$> bTofb (g a)
|
fmodify =
|
||||||
|
error "todo: fmodify"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -208,7 +211,8 @@ fmodify = \(Lens f g) -> \bTofb -> \a -> (f a) <$> bTofb (g a)
|
||||||
-> f b
|
-> f b
|
||||||
-> a
|
-> a
|
||||||
-> f a
|
-> f a
|
||||||
(|=) = \(Lens f _) -> \fb -> \a -> (f a) <$> fb
|
(|=) =
|
||||||
|
error "todo: (|=)"
|
||||||
|
|
||||||
infixl 5 |=
|
infixl 5 |=
|
||||||
|
|
||||||
|
@ -224,7 +228,8 @@ infixl 5 |=
|
||||||
-- prop> let types = (x :: Int, y :: String) in setsetLaw fstL (x, y) z
|
-- prop> let types = (x :: Int, y :: String) in setsetLaw fstL (x, y) z
|
||||||
fstL ::
|
fstL ::
|
||||||
Lens (x, y) x
|
Lens (x, y) x
|
||||||
fstL = Lens (\(_, y) -> \x -> (x, y)) (\(x, _) -> x)
|
fstL =
|
||||||
|
error "todo: fstL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -238,7 +243,8 @@ fstL = Lens (\(_, y) -> \x -> (x, y)) (\(x, _) -> x)
|
||||||
-- prop> let types = (x :: Int, y :: String) in setsetLaw sndL (x, y) z
|
-- prop> let types = (x :: Int, y :: String) in setsetLaw sndL (x, y) z
|
||||||
sndL ::
|
sndL ::
|
||||||
Lens (x, y) y
|
Lens (x, y) y
|
||||||
sndL = Lens (\(x, _) -> \y -> (x, y)) (\(_, y) -> y)
|
sndL =
|
||||||
|
error "todo: sndL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -263,9 +269,8 @@ mapL ::
|
||||||
Ord k =>
|
Ord k =>
|
||||||
k
|
k
|
||||||
-> Lens (Map k v) (Maybe v)
|
-> Lens (Map k v) (Maybe v)
|
||||||
-- Did not really understand this, taken from solutions
|
mapL =
|
||||||
mapL k = Lens (maybe . Map.delete k <*> (flip (Map.insert k)))
|
error "todo: mapL"
|
||||||
(Map.lookup k)
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -290,12 +295,8 @@ setL ::
|
||||||
Ord k =>
|
Ord k =>
|
||||||
k
|
k
|
||||||
-> Lens (Set k) Bool
|
-> Lens (Set k) Bool
|
||||||
-- Set k -> Bool -> Set k
|
setL =
|
||||||
-- Set k -> Bool
|
error "todo: setL"
|
||||||
setL k = Lens (\sk -> \bool -> case bool of
|
|
||||||
True -> Set.insert k sk
|
|
||||||
False -> Set.delete k sk)
|
|
||||||
(\sk -> Set.member k sk)
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -308,7 +309,8 @@ compose ::
|
||||||
Lens b c
|
Lens b c
|
||||||
-> Lens a b
|
-> Lens a b
|
||||||
-> Lens a c
|
-> Lens a c
|
||||||
compose (Lens f g) (Lens h i) = Lens (\a -> h a . f (i a)) (g . i)
|
compose =
|
||||||
|
error "todo: compose"
|
||||||
|
|
||||||
-- | An alias for @compose@.
|
-- | An alias for @compose@.
|
||||||
(|.) ::
|
(|.) ::
|
||||||
|
@ -329,7 +331,8 @@ infixr 9 |.
|
||||||
-- 4
|
-- 4
|
||||||
identity ::
|
identity ::
|
||||||
Lens a a
|
Lens a a
|
||||||
identity = Lens (\_ -> \b -> b) (\a -> a)
|
identity =
|
||||||
|
error "todo: identity"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -342,9 +345,8 @@ product ::
|
||||||
Lens a b
|
Lens a b
|
||||||
-> Lens c d
|
-> Lens c d
|
||||||
-> Lens (a, c) (b, d)
|
-> Lens (a, c) (b, d)
|
||||||
product (Lens f g) (Lens h i) = Lens
|
product =
|
||||||
(\(a, c) -> \(b, d) -> (f a b, h c d))
|
error "todo: product"
|
||||||
(\(a, c) -> (g a, i c))
|
|
||||||
|
|
||||||
-- | An alias for @product@.
|
-- | An alias for @product@.
|
||||||
(***) ::
|
(***) ::
|
||||||
|
@ -373,13 +375,8 @@ choice ::
|
||||||
Lens a x
|
Lens a x
|
||||||
-> Lens b x
|
-> Lens b x
|
||||||
-> Lens (Either a b) x
|
-> Lens (Either a b) x
|
||||||
choice (Lens f g) (Lens h i) = Lens
|
choice =
|
||||||
(\eab -> \x -> case eab of
|
error "todo: choice"
|
||||||
Left a -> Left $ f a x
|
|
||||||
Right b -> Right $ h b x)
|
|
||||||
(\eab -> case eab of
|
|
||||||
Left a -> g a
|
|
||||||
Right b -> i b)
|
|
||||||
|
|
||||||
-- | An alias for @choice@.
|
-- | An alias for @choice@.
|
||||||
(|||) ::
|
(|||) ::
|
||||||
|
@ -466,7 +463,8 @@ addressL =
|
||||||
getSuburb ::
|
getSuburb ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
getSuburb = get $ (compose suburbL addressL)
|
getSuburb =
|
||||||
|
error "todo: getSuburb"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -479,7 +477,8 @@ setStreet ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
-> Person
|
-> Person
|
||||||
setStreet = set $ (compose streetL addressL)
|
setStreet =
|
||||||
|
error "todo: setStreet"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -491,8 +490,8 @@ setStreet = set $ (compose streetL addressL)
|
||||||
getAgeAndCountry ::
|
getAgeAndCountry ::
|
||||||
(Person, Locality)
|
(Person, Locality)
|
||||||
-> (Int, String)
|
-> (Int, String)
|
||||||
getAgeAndCountry (person, locality) = (get ageL person,
|
getAgeAndCountry =
|
||||||
get countryL locality)
|
error "todo: getAgeAndCountry"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -503,9 +502,8 @@ getAgeAndCountry (person, locality) = (get ageL person,
|
||||||
-- (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 (person, address) (city, locality) =
|
setCityAndLocality =
|
||||||
(set (cityL |. localityL |. addressL) person city,
|
error "todo: setCityAndLocality"
|
||||||
set localityL address locality)
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -517,9 +515,8 @@ setCityAndLocality (person, address) (city, locality) =
|
||||||
getSuburbOrCity ::
|
getSuburbOrCity ::
|
||||||
Either Address Locality
|
Either Address Locality
|
||||||
-> String
|
-> String
|
||||||
getSuburbOrCity = \soc -> case soc of
|
getSuburbOrCity =
|
||||||
Left address -> get suburbL address
|
error "todo: getSuburbOrCity"
|
||||||
Right locality -> get cityL locality
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -532,9 +529,8 @@ setStreetOrState ::
|
||||||
Either Person Locality
|
Either Person Locality
|
||||||
-> String
|
-> String
|
||||||
-> Either Person Locality
|
-> Either Person Locality
|
||||||
setStreetOrState = \sos -> \ipsos -> case sos of
|
setStreetOrState =
|
||||||
Left person -> Left $ set (streetL |. addressL) person ipsos
|
error "todo: setStreetOrState"
|
||||||
Right locality -> Right $ set stateL locality ipsos
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -546,4 +542,5 @@ setStreetOrState = \sos -> \ipsos -> case sos of
|
||||||
modifyCityUppercase ::
|
modifyCityUppercase ::
|
||||||
Person
|
Person
|
||||||
-> Person
|
-> Person
|
||||||
modifyCityUppercase = (cityL |. localityL |. addressL) %~ map toUpper
|
modifyCityUppercase =
|
||||||
|
error "todo: modifyCityUppercase"
|
||||||
|
|
168
src/Lets/Lens.hs
168
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, alterF)
|
import qualified Data.Map as Map(insert, delete, lookup)
|
||||||
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))
|
||||||
|
@ -98,7 +98,7 @@ import Prelude hiding (product)
|
||||||
--
|
--
|
||||||
-- class (Foldable t, Functor t) => Traversable t where
|
-- class (Foldable t, Functor t) => Traversable t where
|
||||||
-- traverse ::
|
-- traverse ::
|
||||||
-- Applicative f =>
|
-- Applicative f =>
|
||||||
-- (a -> f b)
|
-- (a -> f b)
|
||||||
-- -> t a
|
-- -> t a
|
||||||
-- -> f (t b)
|
-- -> f (t b)
|
||||||
|
@ -111,15 +111,17 @@ fmapT ::
|
||||||
(a -> b)
|
(a -> b)
|
||||||
-> t a
|
-> t a
|
||||||
-> t b
|
-> t b
|
||||||
fmapT f = getIdentity . traverse (Identity . f)
|
fmapT =
|
||||||
|
error "todo: fmapT"
|
||||||
|
|
||||||
-- | Let's refactor out the call to @traverse@ as an argument to @fmapT@.
|
-- | Let's refactor out the call to @traverse@ as an argument to @fmapT@.
|
||||||
over ::
|
over ::
|
||||||
((a -> Identity b) -> s -> Identity t)
|
((a -> Identity b) -> s -> Identity t)
|
||||||
-> (a -> b)
|
-> (a -> b)
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
over t f = getIdentity . t (Identity . f)
|
over =
|
||||||
|
error "todo: over"
|
||||||
|
|
||||||
-- | Here is @fmapT@ again, passing @traverse@ to @over@.
|
-- | Here is @fmapT@ again, passing @traverse@ to @over@.
|
||||||
fmapTAgain ::
|
fmapTAgain ::
|
||||||
|
@ -127,7 +129,8 @@ fmapTAgain ::
|
||||||
(a -> b)
|
(a -> b)
|
||||||
-> t a
|
-> t a
|
||||||
-> t b
|
-> t b
|
||||||
fmapTAgain = over traverse
|
fmapTAgain =
|
||||||
|
error "todo: fmapTAgain"
|
||||||
|
|
||||||
-- | Let's create a type-alias for this type of function.
|
-- | Let's create a type-alias for this type of function.
|
||||||
type Set s t a b =
|
type Set s t a b =
|
||||||
|
@ -139,20 +142,23 @@ type Set s t a b =
|
||||||
-- unwrapping.
|
-- unwrapping.
|
||||||
sets ::
|
sets ::
|
||||||
((a -> b) -> s -> t)
|
((a -> b) -> s -> t)
|
||||||
-> Set s t a b
|
-> Set s t a b
|
||||||
sets f g = Identity . f (getIdentity . g)
|
sets =
|
||||||
|
error "todo: sets"
|
||||||
|
|
||||||
mapped ::
|
mapped ::
|
||||||
Functor f =>
|
Functor f =>
|
||||||
Set (f a) (f b) a b
|
Set (f a) (f b) a b
|
||||||
mapped f g = Identity (getIdentity . f <$> g)
|
mapped =
|
||||||
|
error "todo: mapped"
|
||||||
|
|
||||||
set ::
|
set ::
|
||||||
Set s t a b
|
Set s t a b
|
||||||
-> s
|
-> s
|
||||||
-> b
|
-> b
|
||||||
-> t
|
-> t
|
||||||
set f s b = over f (const b) s
|
set =
|
||||||
|
error "todo: set"
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -164,7 +170,8 @@ foldMapT ::
|
||||||
(a -> b)
|
(a -> b)
|
||||||
-> t a
|
-> t a
|
||||||
-> b
|
-> b
|
||||||
foldMapT f = getConst . traverse (Const . f)
|
foldMapT =
|
||||||
|
error "todo: foldMapT"
|
||||||
|
|
||||||
-- | Let's refactor out the call to @traverse@ as an argument to @foldMapT@.
|
-- | Let's refactor out the call to @traverse@ as an argument to @foldMapT@.
|
||||||
foldMapOf ::
|
foldMapOf ::
|
||||||
|
@ -172,7 +179,8 @@ foldMapOf ::
|
||||||
-> (a -> r)
|
-> (a -> r)
|
||||||
-> s
|
-> s
|
||||||
-> r
|
-> r
|
||||||
foldMapOf t f = getConst . t (Const . f)
|
foldMapOf =
|
||||||
|
error "todo: foldMapOf"
|
||||||
|
|
||||||
-- | Here is @foldMapT@ again, passing @traverse@ to @foldMapOf@.
|
-- | Here is @foldMapT@ again, passing @traverse@ to @foldMapOf@.
|
||||||
foldMapTAgain ::
|
foldMapTAgain ::
|
||||||
|
@ -180,7 +188,8 @@ foldMapTAgain ::
|
||||||
(a -> b)
|
(a -> b)
|
||||||
-> t a
|
-> t a
|
||||||
-> b
|
-> b
|
||||||
foldMapTAgain = foldMapOf traverse
|
foldMapTAgain =
|
||||||
|
error "todo: foldMapTAgain"
|
||||||
|
|
||||||
-- | Let's create a type-alias for this type of function.
|
-- | Let's create a type-alias for this type of function.
|
||||||
type Fold s t a b =
|
type Fold s t a b =
|
||||||
|
@ -197,12 +206,14 @@ folds ::
|
||||||
-> (a -> Const b a)
|
-> (a -> Const b a)
|
||||||
-> s
|
-> s
|
||||||
-> Const t s
|
-> Const t s
|
||||||
folds f g s = let t = (f (getConst . g) s) in Const t
|
folds =
|
||||||
|
error "todo: folds"
|
||||||
|
|
||||||
folded ::
|
folded ::
|
||||||
Foldable f =>
|
Foldable f =>
|
||||||
Fold (f a) (f a) a a
|
Fold (f a) (f a) a a
|
||||||
folded = folds foldMap
|
folded =
|
||||||
|
error "todo: folded"
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -216,7 +227,8 @@ get ::
|
||||||
Get a s a
|
Get a s a
|
||||||
-> s
|
-> s
|
||||||
-> a
|
-> a
|
||||||
get f = getConst . f Const
|
get =
|
||||||
|
error "todo: get"
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -231,20 +243,20 @@ type Traversal s t a b =
|
||||||
-- | Traverse both sides of a pair.
|
-- | Traverse both sides of a pair.
|
||||||
both ::
|
both ::
|
||||||
Traversal (a, a) (b, b) a b
|
Traversal (a, a) (b, b) a b
|
||||||
-- both :: (a -> f b) -> (a , a) -> f (b , b)
|
both =
|
||||||
both f (a, b) = (,) <$> f a <*> f b
|
error "todo: both"
|
||||||
|
|
||||||
-- | Traverse the left side of @Either@.
|
-- | Traverse the left side of @Either@.
|
||||||
traverseLeft ::
|
traverseLeft ::
|
||||||
Traversal (Either a x) (Either b x) a b
|
Traversal (Either a x) (Either b x) a b
|
||||||
traverseLeft f (Left a) = Left <$> f a
|
traverseLeft =
|
||||||
traverseLeft _ (Right x) = pure $ Right x
|
error "todo: traverseLeft"
|
||||||
|
|
||||||
-- | Traverse the right side of @Either@.
|
-- | Traverse the right side of @Either@.
|
||||||
traverseRight ::
|
traverseRight ::
|
||||||
Traversal (Either x a) (Either x b) a b
|
Traversal (Either x a) (Either x b) a b
|
||||||
traverseRight _ (Left x) = pure $ Left x
|
traverseRight =
|
||||||
traverseRight f (Right b) = Right <$> f b
|
error "todo: traverseRight"
|
||||||
|
|
||||||
type Traversal' a b =
|
type Traversal' a b =
|
||||||
Traversal a a b b
|
Traversal a a b b
|
||||||
|
@ -274,39 +286,44 @@ 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 h = let rh = right h in dimap (either Right (Left . Right)) (either pure (fmap Left)) rh
|
_Left =
|
||||||
_Left h = let lh = left h in dimap (either Left (Right . Right)) (either (fmap Left) pure) lh
|
error "todo: _Left"
|
||||||
|
|
||||||
_Right ::
|
_Right ::
|
||||||
Prism (Either x a) (Either x b) a b
|
Prism (Either x a) (Either x b) a b
|
||||||
_Right h = let rh = right h in dimap (either (Left . Left) Right) (either pure (fmap Right)) rh
|
_Right =
|
||||||
|
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 bToT sToEta pafb = let rh = right pafb in dimap sToEta (either pure (fmap bToT)) rh
|
prism =
|
||||||
|
error "todo: prism"
|
||||||
|
|
||||||
_Just ::
|
_Just ::
|
||||||
Prism (Maybe a) (Maybe b) a b
|
Prism (Maybe a) (Maybe b) a b
|
||||||
_Just = prism Just (maybe (Left Nothing) Right)
|
_Just =
|
||||||
|
error "todo: _Just"
|
||||||
|
|
||||||
_Nothing ::
|
_Nothing ::
|
||||||
Prism (Maybe a) (Maybe a) () ()
|
Prism (Maybe a) (Maybe a) () ()
|
||||||
_Nothing = prism (\_ -> Nothing) (maybe (Right ()) (Left . Just))
|
_Nothing =
|
||||||
|
error "todo: _Nothing"
|
||||||
|
|
||||||
setP ::
|
setP ::
|
||||||
Prism s t a b
|
Prism s t a b
|
||||||
-> s
|
-> s
|
||||||
-> Either t a
|
-> Either t a
|
||||||
setP p = let pl = p Left in either Right Left . pl
|
setP _ _ =
|
||||||
|
error "todo: setP"
|
||||||
|
|
||||||
getP ::
|
getP ::
|
||||||
Prism s t a b
|
Prism s t a b
|
||||||
-> b
|
-> b
|
||||||
-> t
|
-> t
|
||||||
-- Copied :(
|
getP _ _ =
|
||||||
getP p = let pti = p . Tagged . Identity in getIdentity . getTagged . pti
|
error "todo: getP"
|
||||||
|
|
||||||
type Prism' a b =
|
type Prism' a b =
|
||||||
Prism a a b b
|
Prism a a b b
|
||||||
|
@ -329,7 +346,8 @@ modify ::
|
||||||
-> (a -> b)
|
-> (a -> b)
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
modify l f = getIdentity . l (Identity . f)
|
modify _ _ _ =
|
||||||
|
error "todo: modify"
|
||||||
|
|
||||||
-- | An alias for @modify@.
|
-- | An alias for @modify@.
|
||||||
(%~) ::
|
(%~) ::
|
||||||
|
@ -358,7 +376,8 @@ infixr 4 %~
|
||||||
-> b
|
-> b
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
(.~) l = let ml = modify l in ml . const
|
(.~) _ _ _ =
|
||||||
|
error "todo: (.~)"
|
||||||
|
|
||||||
infixl 5 .~
|
infixl 5 .~
|
||||||
|
|
||||||
|
@ -377,8 +396,9 @@ fmodify ::
|
||||||
Lens s t a b
|
Lens s t a b
|
||||||
-> (a -> f b)
|
-> (a -> f b)
|
||||||
-> s
|
-> s
|
||||||
-> f t
|
-> f t
|
||||||
fmodify l = l
|
fmodify _ _ _ =
|
||||||
|
error "todo: fmodify"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -393,7 +413,8 @@ fmodify l = l
|
||||||
-> f b
|
-> f b
|
||||||
-> s
|
-> s
|
||||||
-> f t
|
-> f t
|
||||||
(|=) l = let fl = fmodify l in fl . const
|
(|=) _ _ _ =
|
||||||
|
error "todo: (|=)"
|
||||||
|
|
||||||
infixl 5 |=
|
infixl 5 |=
|
||||||
|
|
||||||
|
@ -403,7 +424,8 @@ infixl 5 |=
|
||||||
-- (30,"abc")
|
-- (30,"abc")
|
||||||
fstL ::
|
fstL ::
|
||||||
Lens (a, x) (b, x) a b
|
Lens (a, x) (b, x) a b
|
||||||
fstL f (x, y) = let fx = f x in fmap (\x' -> (x', y)) fx
|
fstL =
|
||||||
|
error "todo: fstL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -411,7 +433,8 @@ fstL f (x, y) = let fx = f x in fmap (\x' -> (x', y)) fx
|
||||||
-- (13,"abcdef")
|
-- (13,"abcdef")
|
||||||
sndL ::
|
sndL ::
|
||||||
Lens (x, a) (x, b) a b
|
Lens (x, a) (x, b) a b
|
||||||
sndL f (x, y) = let fy = f y in fmap (\y' -> (x, y')) fy
|
sndL =
|
||||||
|
error "todo: sndL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -486,7 +509,8 @@ 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 l1 l2 = l2 . l1
|
compose _ _ =
|
||||||
|
error "todo: compose"
|
||||||
|
|
||||||
-- | An alias for @compose@.
|
-- | An alias for @compose@.
|
||||||
(|.) ::
|
(|.) ::
|
||||||
|
@ -507,7 +531,8 @@ infixr 9 |.
|
||||||
-- 4
|
-- 4
|
||||||
identity ::
|
identity ::
|
||||||
Lens a b a b
|
Lens a b a b
|
||||||
identity = id
|
identity =
|
||||||
|
error "todo: identity"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -550,9 +575,8 @@ 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 l1 l2 = (\f esq -> case esq of
|
choice _ _ =
|
||||||
Left s -> Left <$> (l1 f s)
|
error "todo: choice"
|
||||||
Right q -> Right <$> (l2 f q))
|
|
||||||
|
|
||||||
-- | An alias for @choice@.
|
-- | An alias for @choice@.
|
||||||
(|||) ::
|
(|||) ::
|
||||||
|
@ -635,7 +659,8 @@ intAndL p (IntAnd n a) =
|
||||||
getSuburb ::
|
getSuburb ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
getSuburb = get $ (compose suburbL addressL)
|
getSuburb =
|
||||||
|
error "todo: getSuburb"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -648,7 +673,8 @@ setStreet ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
-> Person
|
-> Person
|
||||||
setStreet = set $ (compose streetL addressL)
|
setStreet =
|
||||||
|
error "todo: setStreet"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -660,8 +686,8 @@ setStreet = set $ (compose streetL addressL)
|
||||||
getAgeAndCountry ::
|
getAgeAndCountry ::
|
||||||
(Person, Locality)
|
(Person, Locality)
|
||||||
-> (Int, String)
|
-> (Int, String)
|
||||||
getAgeAndCountry (person, locality) = (get ageL person,
|
getAgeAndCountry =
|
||||||
get countryL locality)
|
error "todo: getAgeAndCountry"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -672,10 +698,9 @@ getAgeAndCountry (person, locality) = (get ageL person,
|
||||||
-- (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 (person, address) (city, locality) =
|
setCityAndLocality =
|
||||||
(set (cityL |. localityL |. addressL) person city,
|
error "todo: setCityAndLocality"
|
||||||
set localityL address locality)
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >>> getSuburbOrCity (Left maryAddress)
|
-- >>> getSuburbOrCity (Left maryAddress)
|
||||||
|
@ -687,7 +712,7 @@ getSuburbOrCity ::
|
||||||
Either Address Locality
|
Either Address Locality
|
||||||
-> String
|
-> String
|
||||||
getSuburbOrCity =
|
getSuburbOrCity =
|
||||||
get (suburbL ||| cityL)
|
error "todo: getSuburbOrCity"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -701,7 +726,7 @@ setStreetOrState ::
|
||||||
-> String
|
-> String
|
||||||
-> Either Person Locality
|
-> Either Person Locality
|
||||||
setStreetOrState =
|
setStreetOrState =
|
||||||
set (streetL |. addressL ||| stateL)
|
error "todo: setStreetOrState"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -714,20 +739,22 @@ modifyCityUppercase ::
|
||||||
Person
|
Person
|
||||||
-> Person
|
-> Person
|
||||||
modifyCityUppercase =
|
modifyCityUppercase =
|
||||||
cityL |. localityL |. addressL %~ map toUpper
|
error "todo: modifyCityUppercase"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >>> modify intAndL (even . length) (IntAnd 10 "abc")
|
-- >>> modifyIntAndLengthEven (IntAnd 10 "abc")
|
||||||
-- IntAnd 10 False
|
-- IntAnd 10 False
|
||||||
--
|
--
|
||||||
-- >>> modify intAndL (even . length) (IntAnd 10 "abcd")
|
-- >>> modifyIntAndLengthEven (IntAnd 10 "abcd")
|
||||||
-- IntAnd 10 True
|
-- IntAnd 10 True
|
||||||
modifyIntAndLengthEven ::
|
modifyIntAndLengthEven ::
|
||||||
IntAnd [a]
|
IntAnd [a]
|
||||||
-> IntAnd Bool
|
-> IntAnd Bool
|
||||||
modifyIntAndLengthEven =
|
modifyIntAndLengthEven =
|
||||||
intAndL %~ even . length
|
error "todo: modifyIntAndLengthEven"
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -735,8 +762,8 @@ modifyIntAndLengthEven =
|
||||||
-- Locality "ABC" "DEF" "GHI"
|
-- Locality "ABC" "DEF" "GHI"
|
||||||
traverseLocality ::
|
traverseLocality ::
|
||||||
Traversal' Locality String
|
Traversal' Locality String
|
||||||
traverseLocality f (Locality c t y) =
|
traverseLocality =
|
||||||
Locality <$> f c <*> f t <*> f y
|
error "todo: traverseLocality"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -748,32 +775,25 @@ traverseLocality f (Locality c t y) =
|
||||||
intOrIntP ::
|
intOrIntP ::
|
||||||
Prism' (IntOr a) Int
|
Prism' (IntOr a) Int
|
||||||
intOrIntP =
|
intOrIntP =
|
||||||
prism
|
error "todo: intOrIntP"
|
||||||
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 =
|
||||||
prism
|
error "todo: intOrP"
|
||||||
IntOrIsNot
|
|
||||||
(\i -> case i of
|
|
||||||
IntOrIs n -> Left (IntOrIs n)
|
|
||||||
IntOrIsNot a -> Right a)
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >> over intOrP (even . length) (IntOrIsNot "abc")
|
-- >> intOrLengthEven (IntOrIsNot "abc")
|
||||||
-- IntOrIsNot False
|
-- IntOrIsNot False
|
||||||
--
|
--
|
||||||
-- >>> over intOrP (even . length) (IntOrIsNot "abcd")
|
-- >>> intOrLengthEven (IntOrIsNot "abcd")
|
||||||
-- IntOrIsNot True
|
-- IntOrIsNot True
|
||||||
--
|
--
|
||||||
-- >>> over intOrP (even . length) (IntOrIs 10)
|
-- >>> intOrLengthEven (IntOrIs 10)
|
||||||
-- IntOrIs 10
|
-- IntOrIs 10
|
||||||
intOrLengthEven ::
|
intOrLengthEven ::
|
||||||
IntOr [a]
|
IntOr [a]
|
||||||
-> IntOr Bool
|
-> IntOr Bool
|
||||||
intOrLengthEven = over intOrP (even . length)
|
intOrLengthEven =
|
||||||
|
error "todo: intOrLengthEven"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
{-# LANGUAGE TupleSections #-}
|
|
||||||
|
|
||||||
module Lets.OpticPolyLens (
|
module Lets.OpticPolyLens (
|
||||||
Lens(..)
|
Lens(..)
|
||||||
|
@ -44,10 +43,9 @@ module Lets.OpticPolyLens (
|
||||||
, modifyIntandLengthEven
|
, modifyIntandLengthEven
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Bool(bool)
|
import Data.Char(toUpper)
|
||||||
import Data.Char(toUpper, ord)
|
|
||||||
import Data.Map(Map)
|
import Data.Map(Map)
|
||||||
import qualified Data.Map as Map(insert, delete, lookup, fromList, alterF)
|
import qualified Data.Map as Map(insert, delete, lookup)
|
||||||
import Data.Set(Set)
|
import Data.Set(Set)
|
||||||
import qualified Data.Set as Set(insert, delete, member)
|
import qualified Data.Set as Set(insert, delete, member)
|
||||||
import Lets.Data(AlongsideLeft(AlongsideLeft, getAlongsideLeft), AlongsideRight(AlongsideRight, getAlongsideRight), Identity(Identity, getIdentity), Const(Const, getConst), IntAnd(IntAnd), Person(Person), Locality(Locality), Address(Address))
|
import Lets.Data(AlongsideLeft(AlongsideLeft, getAlongsideLeft), AlongsideRight(AlongsideRight, getAlongsideRight), Identity(Identity, getIdentity), Const(Const, getConst), IntAnd(IntAnd), Person(Person), Locality(Locality), Address(Address))
|
||||||
|
@ -64,30 +62,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)
|
||||||
|
|
||||||
-- Lens s t a b
|
|
||||||
|
|
||||||
-- Lens u w s t
|
|
||||||
-- (s -> f t) -> w -> f w
|
|
||||||
|
|
||||||
-- Lens u w s t . Lens s t a b
|
|
||||||
|
|
||||||
-- p :: (->)
|
|
||||||
-- p a b
|
|
||||||
|
|
||||||
-- f :: s -> a
|
|
||||||
-- fcps :: forall r . (a -> r) -> s -> r
|
|
||||||
-- f ~ fcps id
|
|
||||||
-- fcps = \c -> c . f
|
|
||||||
-- (a -> r) . s -> a
|
|
||||||
-- forall r . (a -> f r) -> s -> f r
|
|
||||||
-- 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) s = let rc = r Const in getConst $ rc s
|
get (Lens r) =
|
||||||
|
getConst . r Const
|
||||||
|
|
||||||
set ::
|
set ::
|
||||||
Lens s t a b
|
Lens s t a b
|
||||||
|
@ -145,9 +125,8 @@ modify ::
|
||||||
-> (a -> b)
|
-> (a -> b)
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
modify (Lens r) f s = let idf = Identity . f in
|
modify =
|
||||||
let ridf = r idf in
|
error "todo: modify"
|
||||||
let sidt = ridf s in getIdentity sidt
|
|
||||||
|
|
||||||
-- | An alias for @modify@.
|
-- | An alias for @modify@.
|
||||||
(%~) ::
|
(%~) ::
|
||||||
|
@ -176,10 +155,8 @@ infixr 4 %~
|
||||||
-> b
|
-> b
|
||||||
-> s
|
-> s
|
||||||
-> t
|
-> t
|
||||||
-- modify :: Lens s t a b -> (a -> b) -> s -> t
|
(.~) =
|
||||||
-- modify (Lens r) f s = let idf = Identity . f in
|
error "todo: (.~)"
|
||||||
-- let ridf = r idf in (getIdentity . ridf) s
|
|
||||||
(.~) (Lens stab) b s = getIdentity (stab (\_ -> Identity b) s)
|
|
||||||
|
|
||||||
infixl 5 .~
|
infixl 5 .~
|
||||||
|
|
||||||
|
@ -199,7 +176,8 @@ fmodify ::
|
||||||
-> (a -> f b)
|
-> (a -> f b)
|
||||||
-> s
|
-> s
|
||||||
-> f t
|
-> f t
|
||||||
fmodify (Lens stab) aTofb s = stab aTofb s
|
fmodify =
|
||||||
|
error "todo: fmodify"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -214,7 +192,8 @@ fmodify (Lens stab) aTofb s = stab aTofb s
|
||||||
-> f b
|
-> f b
|
||||||
-> s
|
-> s
|
||||||
-> f t
|
-> f t
|
||||||
(|=) (Lens l) fb s = (l (\_ -> fb) s)
|
(|=) =
|
||||||
|
error "todo: (|=)"
|
||||||
|
|
||||||
infixl 5 |=
|
infixl 5 |=
|
||||||
|
|
||||||
|
@ -230,7 +209,8 @@ infixl 5 |=
|
||||||
-- prop> let types = (x :: Int, y :: String) in setsetLaw fstL (x, y) z
|
-- prop> let types = (x :: Int, y :: String) in setsetLaw fstL (x, y) z
|
||||||
fstL ::
|
fstL ::
|
||||||
Lens (a, x) (b, x) a b
|
Lens (a, x) (b, x) a b
|
||||||
fstL = Lens (\f -> \(a, x) -> let fb = f a in (, x) <$> fb)
|
fstL =
|
||||||
|
error "todo: fstL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -244,7 +224,8 @@ fstL = Lens (\f -> \(a, x) -> let fb = f a in (, x) <$> fb)
|
||||||
-- prop> let types = (x :: Int, y :: String) in setsetLaw sndL (x, y) z
|
-- prop> let types = (x :: Int, y :: String) in setsetLaw sndL (x, y) z
|
||||||
sndL ::
|
sndL ::
|
||||||
Lens (x, a) (x, b) a b
|
Lens (x, a) (x, b) a b
|
||||||
sndL = Lens (\f -> \(x, a) -> let fb = f a in (x ,) <$> fb)
|
sndL =
|
||||||
|
error "todo: sndL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -269,7 +250,8 @@ mapL ::
|
||||||
Ord k =>
|
Ord k =>
|
||||||
k
|
k
|
||||||
-> Lens (Map k v) (Map k v) (Maybe v) (Maybe v)
|
-> Lens (Map k v) (Map k v) (Maybe v) (Maybe v)
|
||||||
mapL k = Lens (\f -> \mkv -> Map.alterF f k mkv)
|
mapL =
|
||||||
|
error "todo: mapL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -294,8 +276,8 @@ setL ::
|
||||||
Ord k =>
|
Ord k =>
|
||||||
k
|
k
|
||||||
-> Lens (Set k) (Set k) Bool Bool
|
-> Lens (Set k) (Set k) Bool Bool
|
||||||
setL k = Lens (\f -> \sk -> (\b -> bool (Set.delete k sk) (Set.insert k sk) b)
|
setL =
|
||||||
<$> (f $ Set.member k sk))
|
error "todo: setL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -308,7 +290,8 @@ 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 (Lens r) (Lens g) = Lens $ g . r
|
compose =
|
||||||
|
error "todo: compose"
|
||||||
|
|
||||||
-- | An alias for @compose@.
|
-- | An alias for @compose@.
|
||||||
(|.) ::
|
(|.) ::
|
||||||
|
@ -329,7 +312,8 @@ infixr 9 |.
|
||||||
-- 4
|
-- 4
|
||||||
identity ::
|
identity ::
|
||||||
Lens a b a b
|
Lens a b a b
|
||||||
identity = Lens (\f -> \a -> f a)
|
identity =
|
||||||
|
error "todo: identity"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -372,9 +356,8 @@ 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 (Lens l) (Lens g) = Lens (\f -> \esq -> case esq of
|
choice =
|
||||||
Left s -> Left <$> l f s
|
error "todo: choice"
|
||||||
Right q -> Right <$> g f q)
|
|
||||||
|
|
||||||
-- | An alias for @choice@.
|
-- | An alias for @choice@.
|
||||||
(|||) ::
|
(|||) ::
|
||||||
|
@ -468,7 +451,9 @@ intAndL =
|
||||||
getSuburb ::
|
getSuburb ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
getSuburb = get $ (compose suburbL addressL)
|
getSuburb =
|
||||||
|
error "todo: getSuburb"
|
||||||
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -481,7 +466,8 @@ setStreet ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
-> Person
|
-> Person
|
||||||
setStreet = set $ (compose streetL addressL)
|
setStreet =
|
||||||
|
error "todo: setStreet"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -493,8 +479,8 @@ setStreet = set $ (compose streetL addressL)
|
||||||
getAgeAndCountry ::
|
getAgeAndCountry ::
|
||||||
(Person, Locality)
|
(Person, Locality)
|
||||||
-> (Int, String)
|
-> (Int, String)
|
||||||
getAgeAndCountry (person, locality) = (get ageL person,
|
getAgeAndCountry =
|
||||||
get countryL locality)
|
error "todo: getAgeAndCountry"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -505,9 +491,8 @@ getAgeAndCountry (person, locality) = (get ageL person,
|
||||||
-- (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 (person, address) (city, locality) =
|
setCityAndLocality =
|
||||||
(set (cityL |. localityL |. addressL) person city,
|
error "todo: setCityAndLocality"
|
||||||
set localityL address locality)
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
|
|
@ -47,12 +47,12 @@ module Lets.StoreLens (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative(Applicative((<*>)))
|
import Control.Applicative(Applicative((<*>)))
|
||||||
import Data.Char(toUpper, ord)
|
import Data.Char(toUpper)
|
||||||
import Data.Functor((<$>))
|
import Data.Functor((<$>))
|
||||||
import Data.Map(Map)
|
import Data.Map(Map)
|
||||||
import qualified Data.Map as Map(insert, delete, lookup, fromList)
|
import qualified Data.Map as Map(insert, delete, lookup)
|
||||||
import Data.Set(Set)
|
import Data.Set(Set)
|
||||||
import qualified Data.Set as Set(insert, delete, member, fromList)
|
import qualified Data.Set as Set(insert, delete, member)
|
||||||
import Lets.Data(Store(Store), Person(Person), Locality(Locality), Address(Address))
|
import Lets.Data(Store(Store), Person(Person), Locality(Locality), Address(Address))
|
||||||
import Prelude hiding (product)
|
import Prelude hiding (product)
|
||||||
|
|
||||||
|
@ -80,37 +80,30 @@ mapS ::
|
||||||
(a -> b)
|
(a -> b)
|
||||||
-> Store s a
|
-> Store s a
|
||||||
-> Store s b
|
-> Store s b
|
||||||
mapS f (Store sToa s) = Store (\ss -> f (sToa ss)) s
|
mapS =
|
||||||
|
error "todo: mapS"
|
||||||
|
|
||||||
duplicateS ::
|
duplicateS ::
|
||||||
Store s a
|
Store s a
|
||||||
-> Store s (Store s a)
|
-> Store s (Store s a)
|
||||||
duplicateS (Store sToa a) = Store (\s -> Store sToa s) a
|
duplicateS =
|
||||||
|
error "todo: duplicateS"
|
||||||
|
|
||||||
extendS ::
|
extendS ::
|
||||||
(Store s a -> b)
|
(Store s a -> b)
|
||||||
-> Store s a
|
-> Store s a
|
||||||
-> Store s b
|
-> Store s b
|
||||||
extendS f = mapS f . duplicateS
|
extendS =
|
||||||
|
error "todo: extendS"
|
||||||
|
|
||||||
extractS ::
|
extractS ::
|
||||||
Store s a
|
Store s a
|
||||||
-> a
|
-> a
|
||||||
extractS = \(Store sToa s) -> sToa s
|
extractS =
|
||||||
|
error "todo: extractS"
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
-- data Lens a b =
|
|
||||||
-- Lens
|
|
||||||
-- (a -> b -> a)
|
|
||||||
-- (a -> b)
|
|
||||||
-- data Store s a = Store (s -> a) s
|
|
||||||
|
|
||||||
-- a -> Store b a
|
|
||||||
-- a -> Store (b -> a) b
|
|
||||||
-- Drop the Store wrapper
|
|
||||||
-- a -> b -> a
|
|
||||||
-- a -> b
|
|
||||||
data Lens a b =
|
data Lens a b =
|
||||||
Lens
|
Lens
|
||||||
(a -> Store b a)
|
(a -> Store b a)
|
||||||
|
@ -200,7 +193,8 @@ modify ::
|
||||||
-> (b -> b)
|
-> (b -> b)
|
||||||
-> a
|
-> a
|
||||||
-> a
|
-> a
|
||||||
modify (Lens f) bTob a = let Store s g = f a in s (bTob g)
|
modify =
|
||||||
|
error "todo: modify"
|
||||||
|
|
||||||
-- | An alias for @modify@.
|
-- | An alias for @modify@.
|
||||||
(%~) ::
|
(%~) ::
|
||||||
|
@ -229,7 +223,8 @@ infixr 4 %~
|
||||||
-> b
|
-> b
|
||||||
-> a
|
-> a
|
||||||
-> a
|
-> a
|
||||||
(.~) = \(Lens f) -> \v -> \a -> let Store s g = f a in s v
|
(.~) =
|
||||||
|
error "todo: (.~)"
|
||||||
|
|
||||||
infixl 5 .~
|
infixl 5 .~
|
||||||
|
|
||||||
|
@ -249,8 +244,9 @@ fmodify ::
|
||||||
-> (b -> f b)
|
-> (b -> f b)
|
||||||
-> a
|
-> a
|
||||||
-> f a
|
-> f a
|
||||||
fmodify (Lens f) bTofb a = let Store s g = f a in s <$> bTofb g
|
fmodify =
|
||||||
|
error "todo: fmodify"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >>> fstL |= Just 3 $ (7, "abc")
|
-- >>> fstL |= Just 3 $ (7, "abc")
|
||||||
|
@ -264,7 +260,8 @@ fmodify (Lens f) bTofb a = let Store s g = f a in s <$> bTofb g
|
||||||
-> f b
|
-> f b
|
||||||
-> a
|
-> a
|
||||||
-> f a
|
-> f a
|
||||||
(|=) (Lens f) fb a = let Store s g = f a in s <$> fb
|
(|=) =
|
||||||
|
error "todo: (|=)"
|
||||||
|
|
||||||
infixl 5 |=
|
infixl 5 |=
|
||||||
|
|
||||||
|
@ -280,7 +277,8 @@ infixl 5 |=
|
||||||
-- prop> let types = (x :: Int, y :: String) in setsetLaw fstL (x, y) z
|
-- prop> let types = (x :: Int, y :: String) in setsetLaw fstL (x, y) z
|
||||||
fstL ::
|
fstL ::
|
||||||
Lens (x, y) x
|
Lens (x, y) x
|
||||||
fstL = Lens (\(x, y) -> Store (\x' -> (x', y)) x)
|
fstL =
|
||||||
|
error "todo: fstL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -294,7 +292,8 @@ fstL = Lens (\(x, y) -> Store (\x' -> (x', y)) x)
|
||||||
-- prop> let types = (x :: Int, y :: String) in setsetLaw sndL (x, y) z
|
-- prop> let types = (x :: Int, y :: String) in setsetLaw sndL (x, y) z
|
||||||
sndL ::
|
sndL ::
|
||||||
Lens (x, y) y
|
Lens (x, y) y
|
||||||
sndL = Lens (\(x, y) -> Store (\y' -> (x, y')) y)
|
sndL =
|
||||||
|
error "todo: sndL"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -319,10 +318,8 @@ mapL ::
|
||||||
Ord k =>
|
Ord k =>
|
||||||
k
|
k
|
||||||
-> Lens (Map k v) (Maybe v)
|
-> Lens (Map k v) (Maybe v)
|
||||||
mapL k = Lens (\mkv -> Store (\mv -> case mv of
|
mapL =
|
||||||
Nothing -> Map.delete k mkv
|
error "todo: mapL"
|
||||||
Just a -> Map.insert k a mkv)
|
|
||||||
(Map.lookup k mkv))
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -347,10 +344,8 @@ setL ::
|
||||||
Ord k =>
|
Ord k =>
|
||||||
k
|
k
|
||||||
-> Lens (Set k) Bool
|
-> Lens (Set k) Bool
|
||||||
setL k = Lens (\sk -> Store (\bool -> case bool of
|
setL =
|
||||||
True -> Set.insert k sk
|
error "todo: setL"
|
||||||
False -> Set.delete k sk)
|
|
||||||
(Set.member k sk))
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -363,10 +358,8 @@ compose ::
|
||||||
Lens b c
|
Lens b c
|
||||||
-> Lens a b
|
-> Lens a b
|
||||||
-> Lens a c
|
-> Lens a c
|
||||||
compose = \(Lens f) -> \(Lens g) ->
|
compose =
|
||||||
Lens (\a -> let Store bToa b = g a
|
error "todo: compose"
|
||||||
in let Store cTob c = f b
|
|
||||||
in Store (bToa . cTob) c)
|
|
||||||
|
|
||||||
-- | An alias for @compose@.
|
-- | An alias for @compose@.
|
||||||
(|.) ::
|
(|.) ::
|
||||||
|
@ -387,8 +380,9 @@ infixr 9 |.
|
||||||
-- 4
|
-- 4
|
||||||
identity ::
|
identity ::
|
||||||
Lens a a
|
Lens a a
|
||||||
identity = Lens (\a -> Store (\a' -> a') a)
|
identity =
|
||||||
|
error "todo: identity"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >>> get (product fstL sndL) (("abc", 3), (4, "def"))
|
-- >>> get (product fstL sndL) (("abc", 3), (4, "def"))
|
||||||
|
@ -400,10 +394,8 @@ product ::
|
||||||
Lens a b
|
Lens a b
|
||||||
-> Lens c d
|
-> Lens c d
|
||||||
-> Lens (a, c) (b, d)
|
-> Lens (a, c) (b, d)
|
||||||
product (Lens f) (Lens g) =
|
product =
|
||||||
Lens (\(a, c) -> let Store h i = f a
|
error "todo: product"
|
||||||
in let Store j k = g c
|
|
||||||
in Store (\(b, d) -> (h b, j d)) (i, k))
|
|
||||||
|
|
||||||
-- | An alias for @product@.
|
-- | An alias for @product@.
|
||||||
(***) ::
|
(***) ::
|
||||||
|
@ -432,10 +424,8 @@ choice ::
|
||||||
Lens a x
|
Lens a x
|
||||||
-> Lens b x
|
-> Lens b x
|
||||||
-> Lens (Either a b) x
|
-> Lens (Either a b) x
|
||||||
choice (Lens ax) (Lens bx) =
|
choice =
|
||||||
Lens (\eab -> case eab of
|
error "todo: choice"
|
||||||
Left a -> let Store f g = ax a in Store (\x -> Left $ f x) g
|
|
||||||
Right b -> let Store h i = bx b in Store (\x -> Right $ h x) i)
|
|
||||||
|
|
||||||
-- | An alias for @choice@.
|
-- | An alias for @choice@.
|
||||||
(|||) ::
|
(|||) ::
|
||||||
|
@ -522,7 +512,8 @@ addressL =
|
||||||
getSuburb ::
|
getSuburb ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
getSuburb = get $ (compose suburbL addressL)
|
getSuburb =
|
||||||
|
error "todo: getSuburb"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -535,7 +526,8 @@ setStreet ::
|
||||||
Person
|
Person
|
||||||
-> String
|
-> String
|
||||||
-> Person
|
-> Person
|
||||||
setStreet = set $ (compose streetL addressL)
|
setStreet =
|
||||||
|
error "todo: setStreet"
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -547,9 +539,8 @@ setStreet = set $ (compose streetL addressL)
|
||||||
getAgeAndCountry ::
|
getAgeAndCountry ::
|
||||||
(Person, Locality)
|
(Person, Locality)
|
||||||
-> (Int, String)
|
-> (Int, String)
|
||||||
getAgeAndCountry (person, locality) = (get ageL person,
|
getAgeAndCountry =
|
||||||
get countryL locality)
|
error "todo: getAgeAndCountry"
|
||||||
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -560,11 +551,9 @@ getAgeAndCountry (person, locality) = (get ageL person,
|
||||||
-- (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 (person, address) (city, locality) =
|
setCityAndLocality =
|
||||||
(set (cityL |. localityL |. addressL) person city,
|
error "todo: setCityAndLocality"
|
||||||
set localityL address locality)
|
|
||||||
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- >>> getSuburbOrCity (Left maryAddress)
|
-- >>> getSuburbOrCity (Left maryAddress)
|
||||||
|
@ -575,10 +564,8 @@ setCityAndLocality (person, address) (city, locality) =
|
||||||
getSuburbOrCity ::
|
getSuburbOrCity ::
|
||||||
Either Address Locality
|
Either Address Locality
|
||||||
-> String
|
-> String
|
||||||
getSuburbOrCity = \soc -> case soc of
|
getSuburbOrCity =
|
||||||
Left address -> get suburbL address
|
error "todo: getSuburbOrCity"
|
||||||
Right locality -> get cityL locality
|
|
||||||
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -591,9 +578,8 @@ setStreetOrState ::
|
||||||
Either Person Locality
|
Either Person Locality
|
||||||
-> String
|
-> String
|
||||||
-> Either Person Locality
|
-> Either Person Locality
|
||||||
setStreetOrState = \sos -> \ipsos -> case sos of
|
setStreetOrState =
|
||||||
Left person -> Left $ set (streetL |. addressL) person ipsos
|
error "todo: setStreetOrState"
|
||||||
Right locality -> Right $ set stateL locality ipsos
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
|
@ -605,4 +591,5 @@ setStreetOrState = \sos -> \ipsos -> case sos of
|
||||||
modifyCityUppercase ::
|
modifyCityUppercase ::
|
||||||
Person
|
Person
|
||||||
-> Person
|
-> Person
|
||||||
modifyCityUppercase = (cityL |. localityL |. addressL) %~ map toUpper
|
modifyCityUppercase =
|
||||||
|
error "todo: modifyCityUppercase"
|
||||||
|
|
66
stack.yaml
66
stack.yaml
|
@ -1,66 +0,0 @@
|
||||||
# This file was automatically generated by 'stack init'
|
|
||||||
#
|
|
||||||
# Some commonly used options have been documented as comments in this file.
|
|
||||||
# For advanced use and comprehensive documentation of the format, please see:
|
|
||||||
# https://docs.haskellstack.org/en/stable/yaml_configuration/
|
|
||||||
|
|
||||||
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
|
|
||||||
# A snapshot resolver dictates the compiler version and the set of packages
|
|
||||||
# to be used for project dependencies. For example:
|
|
||||||
#
|
|
||||||
# resolver: lts-3.5
|
|
||||||
# resolver: nightly-2015-09-21
|
|
||||||
# resolver: ghc-7.10.2
|
|
||||||
#
|
|
||||||
# The location of a snapshot can be provided as a file or url. Stack assumes
|
|
||||||
# a snapshot provided as a file might change, whereas a url resource does not.
|
|
||||||
#
|
|
||||||
# resolver: ./custom-snapshot.yaml
|
|
||||||
# resolver: https://example.com/snapshots/2018-01-01.yaml
|
|
||||||
resolver: lts-14.12
|
|
||||||
|
|
||||||
# User packages to be built.
|
|
||||||
# Various formats can be used as shown in the example below.
|
|
||||||
#
|
|
||||||
# packages:
|
|
||||||
# - some-directory
|
|
||||||
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
|
|
||||||
# subdirs:
|
|
||||||
# - auto-update
|
|
||||||
# - wai
|
|
||||||
packages:
|
|
||||||
- .
|
|
||||||
# Dependency packages to be pulled from upstream that are not in the resolver.
|
|
||||||
# These entries can reference officially published versions as well as
|
|
||||||
# forks / in-progress versions pinned to a git hash. For example:
|
|
||||||
#
|
|
||||||
# extra-deps:
|
|
||||||
# - acme-missiles-0.3
|
|
||||||
# - git: https://github.com/commercialhaskell/stack.git
|
|
||||||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
|
||||||
#
|
|
||||||
# extra-deps: []
|
|
||||||
|
|
||||||
# Override default flag values for local packages and extra-deps
|
|
||||||
# flags: {}
|
|
||||||
|
|
||||||
# Extra package databases containing global packages
|
|
||||||
# extra-package-dbs: []
|
|
||||||
|
|
||||||
# Control whether we use the GHC we find on the path
|
|
||||||
# system-ghc: true
|
|
||||||
#
|
|
||||||
# Require a specific version of stack, using version ranges
|
|
||||||
# require-stack-version: -any # Default
|
|
||||||
# require-stack-version: ">=2.1"
|
|
||||||
#
|
|
||||||
# Override the architecture used by stack, especially useful on Windows
|
|
||||||
# arch: i386
|
|
||||||
# arch: x86_64
|
|
||||||
#
|
|
||||||
# Extra directories used by stack for building
|
|
||||||
# extra-include-dirs: [/path/to/dir]
|
|
||||||
# extra-lib-dirs: [/path/to/dir]
|
|
||||||
#
|
|
||||||
# Allow a newer minor version of GHC than the snapshot specifies
|
|
||||||
# compiler-check: newer-minor
|
|
Loading…
Reference in a new issue