vary 0.1.0.1 → 0.1.0.2
raw patch · 3 files changed
+38/−36 lines, 3 files
Files
- src/Vary.hs +4/−2
- src/Vary/Utils.hs +33/−33
- vary.cabal +1/−1
src/Vary.hs view
@@ -72,12 +72,14 @@ -- >>> import qualified Vary -- -- You probably often want to use it together with the "Vary.Either" module:--- >>> import Vary.Either (VEither(VLeft, VRight))+--+-- >>> import Vary.VEither (VEither(VLeft, VRight)) -- >>> import qualified Vary.VEither as VEither -- -- And for many functions, it is useful (and sometimes outright necessary) to enable the following extensions: ----- >>> :set -XGHC2021 -- Of these, Vary uses: TypeApplications, TypeOperators, FlexibleContexts+-- >>> -- Of the GHC2021 set, Vary uses: TypeApplications, TypeOperators, FlexibleContexts:+-- >>> :set -XGHC2021 -- >>> :set -XDataKinds -- -- Finally, some example snippets in this module make use of 'Data.Function.&', the left-to-right function application operator.
src/Vary/Utils.hs view
@@ -7,22 +7,29 @@ {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE AllowAmbiguousTypes #-} module Vary.Utils(+ -- | + -- This module contains functions and typeclasses/type families (type-level functions)+ -- that are not useful in every day usage,+ -- but are sometimes _very_ useful in:+ --+ -- - highly generic code+ -- - When you want to implement typeclasses for 'Vary'.+ -- - When you want to have access to the internals of Vary to debug something - -- * Useful in generic code+ -- * Useful in generic code and when implementing typeclasses (:|), - KnownPrefix(..), - Length, Subset(..), - Index, - IndexOf, - Mappable, + Mappable,+ Length, + Index,+ IndexOf, pop, - -- * Informational+ -- * Informational (for Debugging) size, activeIndex, - -- * Helper+ -- * Helper functions natValue, ) where @@ -67,22 +74,14 @@ -- | Provide evidence that @xs@ is a subset of @es@.+--+-- This is used to make 'Vary.morph' and 'Vary.VEither.morph' work. class (KnownPrefix es) => Subset (xs :: [Type]) (es :: [Type]) where subsetFullyKnown :: Bool subsetFullyKnown = -- Don't show "minimal complete definition" in haddock. error "subsetFullyKnown" - -- reifyIndices :: [Int]- -- reifyIndices =- -- -- Don't show "minimal complete definition" in haddock.- -- error "reifyIndices"-- -- reifyIndicesVec :: UVector Int- -- reifyIndicesVec =- -- -- Don't show "minimal complete definition" in haddock.- -- error "reifyIndicesVec"- morph' :: Vary xs -> Vary ys morph' = -- Don't show "minimal complete definition" in haddock.@@ -100,31 +99,21 @@ where subsetFullyKnown = False --- reifyIndices = []--- {-# INLINE reifyIndicesVec #-}--- reifyIndicesVec = UVector.empty- -- If the subset is fully known, we're done. instance (KnownPrefix es) => Subset '[] es where subsetFullyKnown = True --- reifyIndices = []--- {-# INLINE reifyIndicesVec #-}--- reifyIndicesVec = UVector.empty -- UVector.empty- instance (e :| es, Subset xs es) => Subset (e : xs) es where subsetFullyKnown = subsetFullyKnown @xs @es - -- reifyIndices = natValue @(IndexOf e es) : reifyIndices @xs @es- -- {-# INLINE reifyIndicesVec #-}- -- reifyIndicesVec = UVector.fromList (natValue @(IndexOf e es) : reifyIndices @xs @es) -- UVector.cons (natValue @(IndexOf e es)) (reifyIndicesVec @xs @es)- morph' (Vary 0 a) = Vary (natValue @(IndexOf e es)) a morph' (Vary n a) = morph' @xs @es (Vary (n - 1) a) ---- -- | Calculate length of a statically known prefix of @es@.+--+-- Used as part of `Subset`. class KnownPrefix (es :: [Type]) where prefixLength :: Int @@ -137,13 +126,15 @@ ---- -- | Require that @xs@ is the unknown suffix of @es@.+--+-- Used as part of `Subset`. class (xs :: [k]) `IsUnknownSuffixOf` (es :: [k]) instance {-# INCOHERENT #-} (xs ~ es) => xs `IsUnknownSuffixOf` es instance (xs `IsUnknownSuffixOf` es) => xs `IsUnknownSuffixOf` (e : es) --- | Get list length+-- | Type-level function to compute the length of a type-level list type family Length (xs :: [k]) :: Nat where Length xs = Length' 0 xs @@ -151,6 +142,9 @@ Length' n '[] = n Length' n (x ': xs) = Length' (n + 1) xs +-- | A slight generalization of 'GHC.TypeLits.natVal' to return arbitrary 'Num'.+--+-- (List indexes are never negative, after all.) natValue :: forall (n :: Nat) a. (KnownNat n, Num a) => a {-# INLINEABLE natValue #-} natValue = fromIntegral (natVal (Proxy :: Proxy n))@@ -168,7 +162,9 @@ 'Text "Cannot map from " ':<>: 'ShowType a ':<>: 'Text " into " ':<>: 'ShowType b :$$: 'Text "as it cannot be found in the list " ':<>: 'ShowType l) --- | Get the first index of a type+-- | Look up the index a particular type has in a type-level-list.+--+-- This index is what is used to determine the tag value stored in a 'Vary'. type IndexOf (x :: k) (xs :: [k]) = IndexOf' (MaybeIndexOf x xs) x xs -- | Get the first index of a type@@ -192,7 +188,11 @@ MaybeIndexOf' n x (x ': xs) = n + 1 MaybeIndexOf' n x (y ': xs) = MaybeIndexOf' (n + 1) x xs --- | Indexed access into the list+-- | Given a type-level index, look up the type at that index.+--+-- If you ever see the @Type_List_Too_Vague...@ in a type error,+-- it means that you need to make the (prefix) of the list of types more concrete+-- by adding some type annotations somewhere. type Index (n :: Nat) (l :: [k]) = Type_List_Too_Vague___Please_Specify_Prefix_Of_List_Including_The_Desired_Type's_Location n l l -- | We use this ridiculous name
vary.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: vary-version: 0.1.0.1+version: 0.1.0.2 synopsis: Vary: Friendly and fast polymorphic variants (open unions/coproducts/extensible sums) description: Vary: Friendly and fast Variant types for Haskell .