{-# LANGUAGE TypeOperators, MultiParamTypeClasses #-}
module Util.Lens (
Lens, lens
, (#)
, (#$), (#=), (%=)
, (<#>)
, map, set, list
) where
import Prelude hiding ((.), map)
import Control.Category ((.))
import qualified Data.Label as Label
import Data.Label (get, lens, modify, (:->))
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Util.Lists as Lists
type Lens a b = a :-> b
(#) :: Lens a b -> Lens b c -> Lens a c
# :: forall a b c. Lens a b -> Lens b c -> Lens a c
(#) = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
(.)
infixr 9 #
(#$) :: Lens f a -> f -> a
#$ :: forall f a. Lens f a -> f -> a
(#$) = forall f a. Lens f a -> f -> a
get
infixr 1 #$
(#=) :: Lens f a -> a -> f -> f
#= :: forall f a. Lens f a -> a -> f -> f
(#=) = forall f a. Lens f a -> a -> f -> f
Label.set
infix 1 #=
(%=) :: Lens f a -> (a -> a) -> f -> f
%= :: forall f a. Lens f a -> (a -> a) -> f -> f
(%=) = forall f a. Lens f a -> (a -> a) -> f -> f
modify
infix 1 %=
(<#>) :: Functor f => Lens a b -> f a -> f b
<#> :: forall (f :: * -> *) a b. Functor f => Lens a b -> f a -> f b
(<#>) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall f a. Lens f a -> f -> a
get
infixl 4 <#>
map :: Ord k => k -> Lens (Map.Map k a) (Maybe a)
map :: forall k a. Ord k => k -> Lens (Map k a) (Maybe a)
map k
k = forall f a. (f -> a) -> ((a -> a) -> f -> f) -> f :-> a
lens (forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
k) (\Maybe a -> Maybe a
modify -> forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter Maybe a -> Maybe a
modify k
k)
set :: Ord k => k -> Lens (Set.Set k) Bool
set :: forall k. Ord k => k -> Lens (Set k) Bool
set k
k = forall f a. (f -> a) -> ((a -> a) -> f -> f) -> f :-> a
lens (forall a. Ord a => a -> Set a -> Bool
Set.member k
k) forall a b. (a -> b) -> a -> b
$ \Bool -> Bool
modify Set k
s ->
if Bool -> Bool
modify (forall a. Ord a => a -> Set a -> Bool
Set.member k
k Set k
s) then forall a. Ord a => a -> Set a -> Set a
Set.insert k
k Set k
s else forall a. Ord a => a -> Set a -> Set a
Set.delete k
k Set k
s
list :: Int -> Lens [a] (Maybe a)
list :: forall a. Int -> Lens [a] (Maybe a)
list Int
i
| Int
i forall a. Ord a => a -> a -> Bool
< Int
0 = forall f a. (f -> a) -> ((a -> a) -> f -> f) -> f :-> a
lens (\[a]
xs -> forall a. [a] -> Maybe a
Lists.head (forall a. Int -> [a] -> [a]
drop (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs forall a. Num a => a -> a -> a
+ Int
i) [a]
xs))
(\Maybe a -> Maybe a
modify [a]
xs -> forall {a}. Int -> (Maybe a -> Maybe a) -> [a] -> [a]
at (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs forall a. Num a => a -> a -> a
+ Int
i) Maybe a -> Maybe a
modify [a]
xs)
| Bool
otherwise = forall f a. (f -> a) -> ((a -> a) -> f -> f) -> f :-> a
lens (forall a. [a] -> Maybe a
Lists.head forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a. Int -> [a] -> [a]
drop Int
i) (forall {a}. Int -> (Maybe a -> Maybe a) -> [a] -> [a]
at Int
i)
where
at :: Int -> (Maybe a -> Maybe a) -> [a] -> [a]
at Int
i Maybe a -> Maybe a
modify [a]
xs = case Maybe a -> Maybe a
modify (forall a. [a] -> Int -> Maybe a
Lists.at [a]
xs Int
i) of
Maybe a
Nothing -> forall a. Int -> [a] -> [a]
Lists.removeAt Int
i [a]
xs
Just a
x -> forall a. Int -> (a -> a) -> [a] -> [a]
Lists.modifyAt Int
i (forall a b. a -> b -> a
const a
x) [a]
xs