bowtie-0.4.0: src/Bowtie/Attr.hs
{-# LANGUAGE UndecidableInstances #-}
module Bowtie.Attr
( HasAttr (..)
, attrLens
, WithAttr (..)
, attrSetter
, memoWithAttr
, memoWithAttrM
, memoWithoutAttr
)
where
import Bowtie.Anno (Anno (..))
import Bowtie.Memo (Memo (..), MemoF, memoFKey, reMkMemo, reMkMemoM, pattern MemoFP, pattern MemoP)
import Bowtie.SMap (Deleted, Inserted, Member, SMap, Val, deleteSMap, indexSMap, insertSMap, updateSMap)
import Data.Kind (Type)
import Data.Proxy (Proxy)
import GHC.TypeLits (KnownSymbol, Symbol)
import Optics (Lens', Setter, lens, sets)
class HasAttr (d :: Type) (s :: Symbol) (k :: Type) where
viewAttr :: Proxy d -> Proxy s -> k -> Val d s
setAttr :: Proxy d -> Proxy s -> Val d s -> k -> k
instance (KnownSymbol s, Member s xs) => HasAttr d s (SMap d xs) where
viewAttr _ = indexSMap
setAttr _ = updateSMap
instance (HasAttr d s k) => HasAttr d s (Anno k x) where
viewAttr pd ps (Anno k _) = viewAttr pd ps k
setAttr pd ps v (Anno k x) = Anno (setAttr pd ps v k) x
instance (HasAttr d s k) => HasAttr d s (MemoF f k x) where
viewAttr pd ps (MemoFP k _) = viewAttr pd ps k
setAttr pd ps v (MemoFP k x) = MemoFP (setAttr pd ps v k) x
instance (HasAttr d s k) => HasAttr d s (Memo f k) where
viewAttr pd ps (MemoP k _) = viewAttr pd ps k
setAttr pd ps v (MemoP k x) = MemoP (setAttr pd ps v k) x
attrLens :: (HasAttr d s k) => Proxy d -> Proxy s -> Lens' k (Val d s)
attrLens pd ps = lens (viewAttr pd ps) (flip (setAttr pd ps))
class (HasAttr d s k) => WithAttr (d :: Type) (s :: Symbol) (k :: Type) (j :: Type) | d s k -> j, d s j -> k where
withAttr :: Proxy d -> Proxy s -> Val d s -> j -> k
withoutAttr :: Proxy d -> Proxy s -> k -> j
instance (KnownSymbol s, Inserted s xs zs, Deleted s zs xs) => WithAttr d s (SMap d zs) (SMap d xs) where
withAttr _ = insertSMap
withoutAttr _ = deleteSMap
instance (WithAttr d s k j) => WithAttr d s (Anno k x) (Anno j x) where
withAttr pd ps v (Anno j x) = Anno (withAttr pd ps v j) x
withoutAttr pd ps (Anno j x) = Anno (withoutAttr pd ps j) x
instance (WithAttr d s k j) => WithAttr d s (MemoF f k x) (MemoF f j x) where
withAttr pd ps v (MemoFP j x) = MemoFP (withAttr pd ps v j) x
withoutAttr pd ps (MemoFP j x) = MemoFP (withoutAttr pd ps j) x
attrSetter :: (WithAttr d s k j) => Proxy d -> Proxy s -> Setter j k () (Val d s)
attrSetter pd ps = sets (\f -> withAttr pd ps (f ()))
memoWithAttr
:: (WithAttr d s k j, Functor f) => Proxy d -> Proxy s -> (MemoF f j (Memo f k) -> Val d s) -> Memo f j -> Memo f k
memoWithAttr pd ps f = reMkMemo (\mfmk -> let v = f mfmk in withAttr pd ps v (memoFKey mfmk))
memoWithAttrM
:: (WithAttr d s k j, Traversable f, Monad m)
=> Proxy d
-> Proxy s
-> (MemoF f j (Memo f k) -> m (Val d s))
-> Memo f j
-> m (Memo f k)
memoWithAttrM pd ps f = reMkMemoM (\mfmk -> fmap (\v -> withAttr pd ps v (memoFKey mfmk)) (f mfmk))
memoWithoutAttr :: (WithAttr d s k j, Functor f) => Proxy d -> Proxy s -> Memo f k -> Memo f j
memoWithoutAttr pd ps = fmap (withoutAttr pd ps)