{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoStarIsType #-}
module Data.Sized.Flipped (Flipped (..)) where

import Control.DeepSeq (NFData (..))
import Control.Lens.At (Index, IxValue, Ixed (..))
import Control.Lens.TH (makeWrapped)
import Control.Lens.Wrapped (_Wrapped)
import Data.Hashable (Hashable (..))
import Data.MonoTraversable (Element, MonoFoldable (..), MonoFunctor (..), MonoTraversable (..))
import qualified Data.Sequence as Seq
import Data.Sized.Internal
import qualified Data.Type.Natural as PN
import Data.Type.Ordinal (Ordinal (..))
import Data.Typeable (Typeable)
import qualified Data.Vector as V
import qualified Data.Vector.Storable as SV
import qualified Data.Vector.Unboxed as UV
import qualified GHC.TypeLits as TL

{- | Wrapper for @'Sized'@ which takes length as its last element, instead of the second.

   Since 0.2.0.0
-}
newtype Flipped f a n = Flipped {forall (f :: Type -> Type) a (n :: Nat).
Flipped f a n -> Sized f n a
runFlipped :: Sized f n a}
  deriving (Int -> Flipped f a n -> ShowS
[Flipped f a n] -> ShowS
Flipped f a n -> String
(Int -> Flipped f a n -> ShowS)
-> (Flipped f a n -> String)
-> ([Flipped f a n] -> ShowS)
-> Show (Flipped f a n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (f :: Type -> Type) a (n :: Nat).
Show (f a) =>
Int -> Flipped f a n -> ShowS
forall (f :: Type -> Type) a (n :: Nat).
Show (f a) =>
[Flipped f a n] -> ShowS
forall (f :: Type -> Type) a (n :: Nat).
Show (f a) =>
Flipped f a n -> String
$cshowsPrec :: forall (f :: Type -> Type) a (n :: Nat).
Show (f a) =>
Int -> Flipped f a n -> ShowS
showsPrec :: Int -> Flipped f a n -> ShowS
$cshow :: forall (f :: Type -> Type) a (n :: Nat).
Show (f a) =>
Flipped f a n -> String
show :: Flipped f a n -> String
$cshowList :: forall (f :: Type -> Type) a (n :: Nat).
Show (f a) =>
[Flipped f a n] -> ShowS
showList :: [Flipped f a n] -> ShowS
Show, Flipped f a n -> Flipped f a n -> Bool
(Flipped f a n -> Flipped f a n -> Bool)
-> (Flipped f a n -> Flipped f a n -> Bool) -> Eq (Flipped f a n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (f :: Type -> Type) a (n :: Nat).
Eq (f a) =>
Flipped f a n -> Flipped f a n -> Bool
$c== :: forall (f :: Type -> Type) a (n :: Nat).
Eq (f a) =>
Flipped f a n -> Flipped f a n -> Bool
== :: Flipped f a n -> Flipped f a n -> Bool
$c/= :: forall (f :: Type -> Type) a (n :: Nat).
Eq (f a) =>
Flipped f a n -> Flipped f a n -> Bool
/= :: Flipped f a n -> Flipped f a n -> Bool
Eq, Eq (Flipped f a n)
Eq (Flipped f a n) =>
(Flipped f a n -> Flipped f a n -> Ordering)
-> (Flipped f a n -> Flipped f a n -> Bool)
-> (Flipped f a n -> Flipped f a n -> Bool)
-> (Flipped f a n -> Flipped f a n -> Bool)
-> (Flipped f a n -> Flipped f a n -> Bool)
-> (Flipped f a n -> Flipped f a n -> Flipped f a n)
-> (Flipped f a n -> Flipped f a n -> Flipped f a n)
-> Ord (Flipped f a n)
Flipped f a n -> Flipped f a n -> Bool
Flipped f a n -> Flipped f a n -> Ordering
Flipped f a n -> Flipped f a n -> Flipped f a n
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Eq (Flipped f a n)
forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Bool
forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Ordering
forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Flipped f a n
$ccompare :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Ordering
compare :: Flipped f a n -> Flipped f a n -> Ordering
$c< :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Bool
< :: Flipped f a n -> Flipped f a n -> Bool
$c<= :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Bool
<= :: Flipped f a n -> Flipped f a n -> Bool
$c> :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Bool
> :: Flipped f a n -> Flipped f a n -> Bool
$c>= :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Bool
>= :: Flipped f a n -> Flipped f a n -> Bool
$cmax :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Flipped f a n
max :: Flipped f a n -> Flipped f a n -> Flipped f a n
$cmin :: forall (f :: Type -> Type) a (n :: Nat).
Ord (f a) =>
Flipped f a n -> Flipped f a n -> Flipped f a n
min :: Flipped f a n -> Flipped f a n -> Flipped f a n
Ord, Typeable, Flipped f a n -> ()
(Flipped f a n -> ()) -> NFData (Flipped f a n)
forall a. (a -> ()) -> NFData a
forall (f :: Type -> Type) a (n :: Nat).
NFData (f a) =>
Flipped f a n -> ()
$crnf :: forall (f :: Type -> Type) a (n :: Nat).
NFData (f a) =>
Flipped f a n -> ()
rnf :: Flipped f a n -> ()
NFData, Eq (Flipped f a n)
Eq (Flipped f a n) =>
(Int -> Flipped f a n -> Int)
-> (Flipped f a n -> Int) -> Hashable (Flipped f a n)
Int -> Flipped f a n -> Int
Flipped f a n -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall (f :: Type -> Type) a (n :: Nat).
Hashable (f a) =>
Eq (Flipped f a n)
forall (f :: Type -> Type) a (n :: Nat).
Hashable (f a) =>
Int -> Flipped f a n -> Int
forall (f :: Type -> Type) a (n :: Nat).
Hashable (f a) =>
Flipped f a n -> Int
$chashWithSalt :: forall (f :: Type -> Type) a (n :: Nat).
Hashable (f a) =>
Int -> Flipped f a n -> Int
hashWithSalt :: Int -> Flipped f a n -> Int
$chash :: forall (f :: Type -> Type) a (n :: Nat).
Hashable (f a) =>
Flipped f a n -> Int
hash :: Flipped f a n -> Int
Hashable)

makeWrapped ''Flipped

type instance Index (Flipped f a n) = Ordinal n

type instance IxValue (Flipped f a n) = IxValue (f a)

type instance Element (Flipped f a n) = Element (Sized f n a)

deriving instance MonoFunctor (f a) => MonoFunctor (Flipped f a n)

deriving instance MonoFoldable (f a) => MonoFoldable (Flipped f a n)

instance (MonoTraversable (f a)) => MonoTraversable (Flipped f a n) where
  otraverse :: forall (f :: Type -> Type).
Applicative f =>
(Element (Flipped f a n) -> f (Element (Flipped f a n)))
-> Flipped f a n -> f (Flipped f a n)
otraverse = (Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n)))
-> Flipped f a n -> f (Flipped f a n)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Flipped f a n)
  (Flipped f a n)
  (Unwrapped (Flipped f a n))
  (Unwrapped (Flipped f a n))
_Wrapped ((Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n)))
 -> Flipped f a n -> f (Flipped f a n))
-> ((Element (f a) -> f (Element (f a)))
    -> Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n)))
-> (Element (f a) -> f (Element (f a)))
-> Flipped f a n
-> f (Flipped f a n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Element (f a) -> f (Element (f a)))
-> Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n))
(Element (Unwrapped (Flipped f a n))
 -> f (Element (Unwrapped (Flipped f a n))))
-> Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n))
forall mono (f :: Type -> Type).
(MonoTraversable mono, Applicative f) =>
(Element mono -> f (Element mono)) -> mono -> f mono
forall (f :: Type -> Type).
Applicative f =>
(Element (Unwrapped (Flipped f a n))
 -> f (Element (Unwrapped (Flipped f a n))))
-> Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n))
otraverse
  {-# INLINE otraverse #-}

  omapM :: forall (f :: Type -> Type).
Applicative f =>
(Element (Flipped f a n) -> f (Element (Flipped f a n)))
-> Flipped f a n -> f (Flipped f a n)
omapM = (Unwrapped (Flipped f a n) -> m (Unwrapped (Flipped f a n)))
-> Flipped f a n -> m (Flipped f a n)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Flipped f a n)
  (Flipped f a n)
  (Unwrapped (Flipped f a n))
  (Unwrapped (Flipped f a n))
_Wrapped ((Unwrapped (Flipped f a n) -> m (Unwrapped (Flipped f a n)))
 -> Flipped f a n -> m (Flipped f a n))
-> ((Element (f a) -> m (Element (f a)))
    -> Unwrapped (Flipped f a n) -> m (Unwrapped (Flipped f a n)))
-> (Element (f a) -> m (Element (f a)))
-> Flipped f a n
-> m (Flipped f a n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Element (f a) -> m (Element (f a)))
-> Unwrapped (Flipped f a n) -> m (Unwrapped (Flipped f a n))
(Element (Unwrapped (Flipped f a n))
 -> m (Element (Unwrapped (Flipped f a n))))
-> Unwrapped (Flipped f a n) -> m (Unwrapped (Flipped f a n))
forall mono (f :: Type -> Type).
(MonoTraversable mono, Applicative f) =>
(Element mono -> f (Element mono)) -> mono -> f mono
forall (f :: Type -> Type).
Applicative f =>
(Element (Unwrapped (Flipped f a n))
 -> f (Element (Unwrapped (Flipped f a n))))
-> Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n))
omapM
  {-# INLINE omapM #-}

instance
  (Integral (Index (f a)), Ixed (f a)) =>
  Ixed (Flipped f a n)
  where
  {-# SPECIALIZE instance Ixed (Flipped [] a (n :: TL.Nat)) #-}
  {-# SPECIALIZE instance Ixed (Flipped [] a (n :: PN.Nat)) #-}
  {-# SPECIALIZE instance Ixed (Flipped V.Vector a (n :: TL.Nat)) #-}
  {-# SPECIALIZE instance Ixed (Flipped V.Vector a (n :: PN.Nat)) #-}
  {-# SPECIALIZE instance SV.Storable a => Ixed (Flipped SV.Vector a (n :: TL.Nat)) #-}
  {-# SPECIALIZE instance SV.Storable a => Ixed (Flipped SV.Vector a (n :: PN.Nat)) #-}
  {-# SPECIALIZE instance UV.Unbox a => Ixed (Flipped UV.Vector a (n :: TL.Nat)) #-}
  {-# SPECIALIZE instance UV.Unbox a => Ixed (Flipped UV.Vector a (n :: PN.Nat)) #-}
  {-# SPECIALIZE instance Ixed (Flipped Seq.Seq a (n :: TL.Nat)) #-}
  {-# SPECIALIZE instance Ixed (Flipped Seq.Seq a (n :: PN.Nat)) #-}
  ix :: Index (Flipped f a n)
-> Traversal' (Flipped f a n) (IxValue (Flipped f a n))
ix Index (Flipped f a n)
o = (Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n)))
-> Flipped f a n -> f (Flipped f a n)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Flipped f a n)
  (Flipped f a n)
  (Unwrapped (Flipped f a n))
  (Unwrapped (Flipped f a n))
_Wrapped ((Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n)))
 -> Flipped f a n -> f (Flipped f a n))
-> ((IxValue (f a) -> f (IxValue (f a)))
    -> Unwrapped (Flipped f a n) -> f (Unwrapped (Flipped f a n)))
-> (IxValue (f a) -> f (IxValue (f a)))
-> Flipped f a n
-> f (Flipped f a n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Unwrapped (Flipped f a n))
-> Traversal'
     (Unwrapped (Flipped f a n)) (IxValue (Unwrapped (Flipped f a n)))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Unwrapped (Flipped f a n))
Index (Flipped f a n)
o
  {-# INLINE ix #-}