{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Vec.Lazy.Inline.Lens (
ix,
_Cons,
_head,
_tail,
_Pull,
_Vec,
) where
import Data.Fin (Fin (..))
import Data.Nat (Nat (..))
import Data.Vec.Lazy.Lens (_Cons, _head, _tail)
import Prelude (Functor, ($), (.))
import qualified Control.Lens as L
import qualified Data.Fin as F
import qualified Data.Type.Nat as N
import qualified Data.Vec.Pull as P
import Data.Vec.Lazy.Inline
ix :: forall n f a. (N.InlineInduction n, Functor f) => Fin n -> L.LensLike' f (Vec n a) a
ix = getIxLens $ N.inlineInduction1 start step where
start :: IxLens f 'Z a
start = IxLens F.absurd
step :: IxLens f m a -> IxLens f ('S m) a
step (IxLens l) = IxLens $ \i -> case i of
FZ -> _head
FS j -> _tail . l j
newtype IxLens f n a = IxLens { getIxLens :: Fin n -> L.LensLike' f (Vec n a) a }
_Pull :: N.InlineInduction n => L.Iso (Vec n a) (Vec n b) (P.Vec n a) (P.Vec n b)
_Pull = L.iso toPull fromPull
_Vec :: N.InlineInduction n => L.Prism' [a] (Vec n a)
_Vec = L.prism' toList fromList