data-diverse-lens 0.5.2.0 → 1.0.0.0
raw patch · 7 files changed
+292/−287 lines, 7 filesdep ~data-diversePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: data-diverse
API changes (from Hackage documentation)
- Data.Diverse.Lens.Many: instance (Data.Diverse.Many.Internal.Select smaller larger, Data.Diverse.Many.Internal.Amend smaller larger) => Data.Generics.Product.Subtype.Subtype (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many larger)
- Data.Diverse.Lens.Many: instance (Data.Diverse.TypeLevel.MemberAt n x xs, ys ~ Data.Diverse.TypeLevel.ReplaceIndex n y xs) => Data.Generics.Product.Positions.HasPosition n (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys) x y
- Data.Diverse.Lens.Many: instance (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Replace (Data.Tagged.Tagged l x) (Data.Tagged.Tagged l y) xs) => Data.Generics.Product.Fields.HasField l (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys) x y
- Data.Diverse.Lens.Many: instance Data.Diverse.TypeLevel.UniqueMember x xs => Data.Generics.Product.Typed.HasType x (Data.Diverse.Many.Internal.Many xs)
- Data.Diverse.Lens.Which: instance (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Generics.Sum.Constructors.AsConstructor l (Data.Diverse.Which.Internal.Which xs) (Data.Diverse.Which.Internal.Which xs) x x
- Data.Diverse.Lens.Which: instance (Data.Diverse.Which.Internal.Diversify branch tree, Data.Diverse.Which.Internal.Reinterpret' branch tree) => Data.Generics.Sum.Subtype.AsSubtype (Data.Diverse.Which.Internal.Which branch) (Data.Diverse.Which.Internal.Which tree)
- Data.Diverse.Lens.Which: instance Data.Diverse.TypeLevel.UniqueMember x xs => Data.Generics.Sum.Typed.AsType x (Data.Diverse.Which.Internal.Which xs)
+ Data.Diverse.Lens.Many: class HasItem a b s t | s a b -> t, t a b -> s
+ Data.Diverse.Lens.Many: genericItemTag :: forall l a b s t. (HasField l s t a b) => Lens s t a b
+ Data.Diverse.Lens.Many: instance (Data.Diverse.Many.Internal.Select smaller larger, Data.Diverse.Many.Internal.Amend smaller smaller' larger, larger' ~ Data.Diverse.TypeLevel.Replaces smaller smaller' larger) => Data.Diverse.Lens.Many.HasProject smaller smaller' larger larger' (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many smaller') (Data.Diverse.Many.Internal.Many larger) (Data.Diverse.Many.Internal.Many larger')
+ Data.Diverse.Lens.Many: instance (Data.Diverse.Many.Internal.Select smaller larger, Data.Diverse.Many.Internal.Amend' smaller larger) => Data.Diverse.Lens.Many.HasProject' smaller larger (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many larger)
+ Data.Diverse.Lens.Many: instance (Data.Diverse.Many.Internal.SelectN ns smaller larger, Data.Diverse.Many.Internal.AmendN ns smaller smaller' larger, larger' ~ Data.Diverse.TypeLevel.ReplacesIndex ns smaller' larger) => Data.Diverse.Lens.Many.HasProjectN ns smaller smaller' larger larger' (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many smaller') (Data.Diverse.Many.Internal.Many larger) (Data.Diverse.Many.Internal.Many larger')
+ Data.Diverse.Lens.Many: instance (Data.Diverse.Many.Internal.SelectN ns smaller larger, Data.Diverse.Many.Internal.AmendN' ns smaller larger) => Data.Diverse.Lens.Many.HasProjectN' ns smaller larger (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many larger)
+ Data.Diverse.Lens.Many: instance (Data.Diverse.TypeLevel.MemberAt n x xs, ys ~ Data.Diverse.TypeLevel.ReplaceIndex n y xs) => Data.Diverse.Lens.Many.HasItemN n x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
+ Data.Diverse.Lens.Many: instance (Data.Diverse.TypeLevel.UniqueMember x xs, ys ~ Data.Diverse.TypeLevel.Replace x y xs) => Data.Diverse.Lens.Many.HasItem x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
+ Data.Diverse.Lens.Many: instance Data.Diverse.TypeLevel.MemberAt n x xs => Data.Diverse.Lens.Many.HasItemN' n x (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Lens.Many: instance Data.Diverse.TypeLevel.UniqueMember x xs => Data.Diverse.Lens.Many.HasItem' x (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Lens.Many: instance forall k (l :: k) (xs :: [*]) x (ys :: [*]) y. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Replace (Data.Tagged.Tagged l x) (Data.Tagged.Tagged l y) xs) => Data.Diverse.Lens.Many.HasItemTag l x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
+ Data.Diverse.Lens.Many: instance forall k (l :: k) (xs :: [*]) x (ys :: [*]) y. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Replace x y xs) => Data.Diverse.Lens.Many.HasItemL l x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
+ Data.Diverse.Lens.Many: instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Many.HasItemTag' l x (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Lens.Many: instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Many.HasItemL' l x (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Lens.Many: instance forall k1 (smaller :: [GHC.Types.Type]) (larger :: [GHC.Types.Type]) (ls :: [k1]). (Data.Diverse.Many.Internal.Select smaller larger, Data.Diverse.Many.Internal.Amend' smaller larger, smaller ~ Data.Diverse.TypeLevel.KindsAtLabels ls larger, Data.Diverse.TypeLevel.IsDistinct ls, Data.Diverse.TypeLevel.UniqueLabels ls larger) => Data.Diverse.Lens.Many.HasProjectL' ls smaller larger (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many larger)
+ Data.Diverse.Lens.Many: instance forall k1 (smaller :: [GHC.Types.Type]) (larger :: [GHC.Types.Type]) (smaller' :: [GHC.Types.Type]) (ls :: [k1]) (larger' :: [GHC.Types.Type]). (Data.Diverse.Many.Internal.Select smaller larger, Data.Diverse.Many.Internal.Amend smaller smaller' larger, smaller ~ Data.Diverse.TypeLevel.KindsAtLabels ls larger, Data.Diverse.TypeLevel.IsDistinct ls, Data.Diverse.TypeLevel.UniqueLabels ls larger, larger' ~ Data.Diverse.TypeLevel.Replaces smaller smaller' larger) => Data.Diverse.Lens.Many.HasProjectL ls smaller smaller' larger larger' (Data.Diverse.Many.Internal.Many smaller) (Data.Diverse.Many.Internal.Many smaller') (Data.Diverse.Many.Internal.Many larger) (Data.Diverse.Many.Internal.Many larger')
+ Data.Diverse.Lens.Which: genericFacetTag :: forall l a s proxy. (AsConstructor l s s a a) => proxy l -> Prism' s a
+ Data.Diverse.Lens.Which: instance (Data.Diverse.Which.Internal.Diversify branch tree, Data.Diverse.Which.Internal.Reinterpret' branch tree) => Data.Diverse.Lens.Which.AsInject branch tree (Data.Diverse.Which.Internal.Which branch) (Data.Diverse.Which.Internal.Which tree)
+ Data.Diverse.Lens.Which: instance (Data.Diverse.Which.Internal.DiversifyN ns branch tree, Data.Diverse.Which.Internal.ReinterpretN' ns branch tree) => Data.Diverse.Lens.Which.AsInjectN ns branch tree (Data.Diverse.Which.Internal.Which branch) (Data.Diverse.Which.Internal.Which tree)
+ Data.Diverse.Lens.Which: instance Data.Diverse.TypeLevel.MemberAt n x xs => Data.Diverse.Lens.Which.AsFacetN n x (Data.Diverse.Which.Internal.Which xs)
+ Data.Diverse.Lens.Which: instance Data.Diverse.TypeLevel.UniqueMember x xs => Data.Diverse.Lens.Which.AsFacet x (Data.Diverse.Which.Internal.Which xs)
+ Data.Diverse.Lens.Which: instance forall k (branch :: [GHC.Types.Type]) (tree :: [GHC.Types.Type]) (ls :: [k]). (Data.Diverse.Which.Internal.Diversify branch tree, Data.Diverse.Which.Internal.Reinterpret' branch tree, branch ~ Data.Diverse.TypeLevel.KindsAtLabels ls tree, Data.Diverse.TypeLevel.UniqueLabels ls tree, Data.Diverse.TypeLevel.IsDistinct ls) => Data.Diverse.Lens.Which.AsInjectL ls branch tree (Data.Diverse.Which.Internal.Which branch) (Data.Diverse.Which.Internal.Which tree)
+ Data.Diverse.Lens.Which: instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Which.AsFacetTag l x (Data.Diverse.Which.Internal.Which xs)
+ Data.Diverse.Lens.Which: instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Which.AsFacetL l x (Data.Diverse.Which.Internal.Which xs)
- Data.Diverse.Lens.Many: item :: forall x xs. UniqueMember x xs => Lens' (Many xs) x
+ Data.Diverse.Lens.Many: item :: HasItem a b s t => Lens s t a b
- Data.Diverse.Lens.Many: item' :: forall x y xs. UniqueMember x xs => Lens (Many xs) (Many (Replace x y xs)) x y
+ Data.Diverse.Lens.Many: item' :: HasItem' a s => Lens' s a
- Data.Diverse.Lens.Many: itemL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens' (Many xs) x
+ Data.Diverse.Lens.Many: itemL :: HasItemL l a b s t => Lens s t a b
- Data.Diverse.Lens.Many: itemL' :: forall l y xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens (Many xs) (Many (Replace x y xs)) x y
+ Data.Diverse.Lens.Many: itemL' :: HasItemL' l a s => Lens' s a
- Data.Diverse.Lens.Many: itemN :: forall n xs proxy x. MemberAt n x xs => proxy n -> Lens' (Many xs) x
+ Data.Diverse.Lens.Many: itemN :: HasItemN n a b s t => Lens s t a b
- Data.Diverse.Lens.Many: itemN' :: forall n y xs proxy x. MemberAt n x xs => proxy n -> Lens (Many xs) (Many (ReplaceIndex n y xs)) x y
+ Data.Diverse.Lens.Many: itemN' :: HasItemN' n a s => Lens' s a
- Data.Diverse.Lens.Many: itemTag :: forall l xs proxy x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => proxy l -> Lens' (Many xs) x
+ Data.Diverse.Lens.Many: itemTag :: HasItemTag l a b s t => Lens s t a b
- Data.Diverse.Lens.Many: itemTag' :: forall l y xs proxy x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => proxy l -> Lens (Many xs) (Many (Replace (Tagged l x) (Tagged l y) xs)) x y
+ Data.Diverse.Lens.Many: itemTag' :: HasItemTag' l a s => Lens' s a
- Data.Diverse.Lens.Many: project :: forall smaller larger. (Select smaller larger, Amend smaller larger) => Lens' (Many larger) (Many smaller)
+ Data.Diverse.Lens.Many: project :: HasProject as bs ss ts a b s t => Lens s t a b
- Data.Diverse.Lens.Many: project' :: forall smaller smaller' larger. (Select smaller larger, Amend' smaller smaller' larger) => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Lens.Many: project' :: HasProject' as ss a s => Lens' s a
- Data.Diverse.Lens.Many: projectL :: forall ls smaller larger proxy. (Select smaller larger, Amend smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Lens' (Many larger) (Many smaller)
+ Data.Diverse.Lens.Many: projectL :: HasProjectL ls as bs ss ts a b s t => Lens s t a b
- Data.Diverse.Lens.Many: projectL' :: forall ls smaller smaller' larger proxy. (Select smaller larger, Amend' smaller smaller' larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Lens.Many: projectL' :: HasProjectL' ls as ss a s => Lens' s a
- Data.Diverse.Lens.Many: projectN :: forall ns smaller larger proxy. (SelectN ns smaller larger, AmendN ns smaller larger) => proxy ns -> Lens' (Many larger) (Many smaller)
+ Data.Diverse.Lens.Many: projectN :: HasProjectN ns as bs ss ts a b s t => Lens s t a b
- Data.Diverse.Lens.Many: projectN' :: forall ns smaller smaller' larger proxy. (SelectN ns smaller larger, AmendN' ns smaller smaller' larger) => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Lens.Many: projectN' :: HasProjectN' ns as ss a s => Lens' s a
- Data.Diverse.Lens.Which: facet :: forall x xs. (UniqueMember x xs) => Prism' (Which xs) x
+ Data.Diverse.Lens.Which: facet :: AsFacet a s => Prism' s a
- Data.Diverse.Lens.Which: facetL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Prism' (Which xs) x
+ Data.Diverse.Lens.Which: facetL :: AsFacetL l a s => Prism' s a
- Data.Diverse.Lens.Which: facetN :: forall n xs proxy x. (MemberAt n x xs) => proxy n -> Prism' (Which xs) x
+ Data.Diverse.Lens.Which: facetN :: AsFacetN n a s => Prism' s a
- Data.Diverse.Lens.Which: facetTag :: forall l xs proxy x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => proxy l -> Prism' (Which xs) x
+ Data.Diverse.Lens.Which: facetTag :: AsFacetTag l a s => Prism' s a
- Data.Diverse.Lens.Which: inject :: forall branch tree. (Diversify branch tree, Reinterpret' branch tree) => Prism' (Which tree) (Which branch)
+ Data.Diverse.Lens.Which: inject :: AsInject as ss a s => Prism' s a
- Data.Diverse.Lens.Which: injectL :: forall ls branch tree proxy. (Diversify branch tree, Reinterpret' branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Prism' (Which tree) (Which branch)
+ Data.Diverse.Lens.Which: injectL :: AsInjectL ls as ss a s => Prism' s a
- Data.Diverse.Lens.Which: injectN :: forall indices branch tree proxy. (DiversifyN indices branch tree, ReinterpretN' indices branch tree) => proxy indices -> Prism' (Which tree) (Which branch)
+ Data.Diverse.Lens.Which: injectN :: AsInjectN ns as ss a s => Prism' s a
- Data.Diverse.Profunctor.Many: projected :: forall a' proxy w a b. (Profunctor w, Strong w, Select a a', Amend' a b a') => proxy a' -> w (Many a) (Many b) -> w (Many a') (Many (Replaces a b a'))
+ Data.Diverse.Profunctor.Many: projected :: forall a' proxy w a b. (Profunctor w, Strong w, Select a a', Amend a b a') => proxy a' -> w (Many a) (Many b) -> w (Many a') (Many (Replaces a b a'))
Files
- README.md +15/−0
- data-diverse-lens.cabal +3/−3
- src/Data/Diverse/Lens/Many.hs +147/−105
- src/Data/Diverse/Lens/Which.hs +57/−62
- src/Data/Diverse/Profunctor/Many.hs +3/−4
- test/Data/Diverse/Lens/ManySpec.hs +51/−82
- test/Data/Diverse/Lens/WhichSpec.hs +16/−31
README.md view
@@ -8,8 +8,23 @@ # Changelog +* 1.0.0.0+ - Removed overlapping instances of Data.Generics lens+ - Using typeclass instead of plain functions so that lens can be used for other data types+ - Added default implementations for some of these typeclasses using Data.Generic typeclasses.+ - Breaking change: the xxx' version of functions are now consistently the simpler or non-polymorphic version - This is more consistent with 'Control.Lens' as well.+ - This means the following are swapped:+ - `item`, `item'`+ - `itemL`, `itemL'`+ - `itemTag`, `itemTag'`+ - `itemN`, `itemN'`+ - `project`, `project'`+ - `projectL`, `projectL'`+ - `projectN`, `projectN'`+ * 0.5.2.0 - Added itemTag and facetTag that also tag/untags the field.+ - Added overlapping instances of Data.Generics lens * 0.5.1.0 - Added faceted, injected, itemized, projected, which is analogous to Profunctor Choice and Strong
data-diverse-lens.cabal view
@@ -1,5 +1,5 @@ name: data-diverse-lens-version: 0.5.2.0+version: 1.0.0.0 synopsis: Isos & Lens for Data.Diverse.Many and Prisms for Data.Diverse.Which description: Isos & Lens for Data.Diverse.Many and Prisms for Data.Diverse.Which Refer to [ManySpec.hs](https://github.com/louispan/data-diverse-lens/blob/master/test/Data/Diverse/Lens/ManySpec.hs) and [WhichSpec.hs](https://github.com/louispan/data-diverse-lens/blob/master/test/Data/Diverse/Lens/WhichSpec.hs) for example usages.@@ -24,7 +24,7 @@ Data.Diverse.Profunctor.Many Data.Diverse.Profunctor.Which build-depends: base >= 4.7 && < 5- , data-diverse >= 1.3.0.0+ , data-diverse >= 2.0.0.0 , tagged >= 0.8.5 , profunctors >= 5.2 , generic-lens >= 0.5.0.0@@ -39,7 +39,7 @@ other-modules: Data.Diverse.Lens.ManySpec Data.Diverse.Lens.WhichSpec build-depends: base- , data-diverse >= 1.3.0.0+ , data-diverse >= 2.0.0.0 , data-diverse-lens , hspec >= 2 , lens >= 4
src/Data/Diverse/Lens/Many.hs view
@@ -1,7 +1,9 @@-{-# OPTIONS_GHC -Wno-orphans #-}-+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-}@@ -17,12 +19,13 @@ -- * Single field -- ** Lens for a single field- , item+ , HasItem(..) , item' , itemL , itemL' , itemTag , itemTag'+ , genericItemTag , itemN , itemN' @@ -40,8 +43,8 @@ import Data.Tagged import Data.Diverse.Many import Data.Diverse.TypeLevel-import Data.Proxy import Data.Generics.Product+import GHC.TypeLits -- | @_Many = iso fromMany toMany@ _Many :: IsMany t xs a => Iso' (Many xs) (t xs a)@@ -53,88 +56,106 @@ ----------------------------------------------------------------------- --- | 'fetch' ('view' 'item') and 'replace' ('set' 'item') in 'Lens'' form.+-- | 'fetch' ('view' 'item') and 'replace'' ('set' 'item'') in 'Lens'' form. -- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'--- x '^.' 'item' \@Int \`shouldBe` 5--- (x '&' 'item' \@Int .~ 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'+-- x '^.' 'item'' \@Int \`shouldBe` 5+-- (x '&' 'item'' \@Int .~ 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' -- @-item :: forall x xs. UniqueMember x xs => Lens' (Many xs) x-item = lens fetch replace+class HasItem' a s where+ item' :: Lens' s a --- | Polymorphic version of 'item'-item' :: forall x y xs. UniqueMember x xs => Lens (Many xs) (Many (Replace x y xs)) x y-item' = lens fetch (replace' @x @y Proxy)+ -- | Make it easy to create an instance of 'item' using 'Data.Generics.Product.Typed'+ default item' :: (HasType a s) => Lens' s a+ item' = typed --- | I'm using "Data.Generics" as the canoical class for HasXXX.--- Overlap 'HasType' 'typed' with the more efficient 'item'--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} UniqueMember x xs => HasType x (Many xs) where- typed = item+instance UniqueMember x xs => HasItem' x (Many xs) where+ item' = lens fetch replace' +-- | Polymorphic version of 'item''+class HasItem a b s t | s a b -> t, t a b -> s where+ item :: Lens s t a b++instance (UniqueMember x xs, ys ~ Replace x y xs) => HasItem x y (Many xs) (Many ys) where+ item = lens fetch (replace @x @y)+ -- | 'fetchL' ('view' 'itemL') and 'replaceL' ('set' 'itemL') in 'Lens'' form. -- -- @ -- let x = (5 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' 'nil'--- x '^.' 'itemL' \@Foo Proxy \`shouldBe` Tagged \@Foo False--- (x '&' 'itemL' \@Foo Proxy '.~' Tagged \@Foo True) \`shouldBe` (5 :: Int) './' Tagged \@Foo True './' Tagged \@Bar \'X' './' 'nil'+-- x '^.' 'itemL'' \@Foo Proxy \`shouldBe` Tagged \@Foo False+-- (x '&' 'itemL'' \@Foo Proxy '.~' Tagged \@Foo True) \`shouldBe` (5 :: Int) './' Tagged \@Foo True './' Tagged \@Bar \'X' './' 'nil' -- @-itemL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs)- => proxy l -> Lens' (Many xs) x-itemL p = lens (fetchL p) (replaceL p)+class HasItemL' (l :: k) a s | s l -> a where+ itemL' :: Lens' s a --- | Polymorphic version of 'itemL'+instance (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => HasItemL' l x (Many xs) where+ itemL' = lens (fetchL @l) (replaceL' @l)++-- | Polymorphic version of 'itemL'' -- -- @ -- let x = (5 :: Int) './' Tagged @Foo False './' Tagged \@Bar \'X' './' 'nil'--- (x '&' itemL' \@Foo Proxy '.~' \"foo") \`shouldBe` (5 :: Int) './' \"foo" './' Tagged \@Bar \'X' './' 'nil'+-- (x '&' 'itemL' \@Foo Proxy '.~' \"foo") \`shouldBe` (5 :: Int) './' \"foo" './' Tagged \@Bar \'X' './' 'nil' -- @-itemL' :: forall l y xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs)- => proxy l -> Lens (Many xs) (Many (Replace x y xs)) x y-itemL' p = lens (fetchL p) (replaceL' p)+class HasItemL (l :: k) a b s t | s l -> a, t l -> b, s l b -> t, t l a -> s where+ itemL :: Lens s t a b --- | Variation of 'itemL' that automatically tags and untags the field.-itemTag :: forall l xs proxy x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs)- => proxy l -> Lens' (Many xs) x-itemTag p = lens (fetchTag p) (replaceTag p)+instance (UniqueLabelMember l xs, x ~ KindAtLabel l xs, ys ~ Replace x y xs)+ => HasItemL l x y (Many xs) (Many ys) where+ itemL = lens (fetchL @l) (replaceL @l) -- | Variation of 'itemL'' that automatically tags and untags the field.-itemTag' :: forall l y xs proxy x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs)- => proxy l -> Lens (Many xs) (Many (Replace (Tagged l x) (Tagged l y) xs)) x y-itemTag' p = lens (fetchTag p) (replaceTag' p)+class HasItemTag' (l :: k) a s | s l -> a where+ itemTag' :: Lens' s a --- | I'm using "Data.Generics" as the canoical class for HasXXX.--- Overlap 'HasField' 'field' with the more efficient 'itemN''--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs, ys ~ Replace (Tagged l x) (Tagged l y) xs) =>- HasField l (Many xs) (Many ys) x y where- field = itemTag' (Proxy @l)+instance (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => HasItemTag' l x (Many xs) where+ itemTag' = lens (fetchTag @l) (replaceTag' @l) --- | 'fetchN' ('view' 'item') and 'replaceN' ('set' 'item') in 'Lens'' form.+-- | Variation of 'itemL' that automatically tags and untags the field.+class HasItemTag (l :: k) a b s t | s l -> a, t l -> b, s l b -> t, t l a -> s where+ itemTag :: Lens s t a b++-- | Make it easy to create an instance of 'itemTag' using 'Data.Generics.Product.Fields'+-- NB. This is not a default signature for HasItemTag, as this makes GHC think that l must be type 'Symbol'+genericItemTag :: forall l a b s t. (HasField l s t a b) => Lens s t a b+genericItemTag = field @l++instance (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs, ys ~ Replace (Tagged l x) (Tagged l y) xs)+ => HasItemTag l x y (Many xs) (Many ys) where+ itemTag = lens (fetchTag @l) (replaceTag @l)++-- | 'fetchN' ('view' 'item') and 'replaceN'' ('set' 'item'') in 'Lens'' form. -- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' ./ nil--- x '^.' 'itemN' (Proxy \@0) \`shouldBe` 5--- (x '&' 'itemN' (Proxy @0) '.~' 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil'+-- x '^.' 'itemN'' (Proxy \@0) \`shouldBe` 5+-- (x '&' 'itemN'' (Proxy @0) '.~' 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil' -- @-itemN :: forall n xs proxy x. MemberAt n x xs => proxy n -> Lens' (Many xs) x-itemN p = lens (fetchN p) (replaceN p)+class HasItemN' (n :: Nat) a s | s n -> a where+ itemN' :: Lens' s a +instance (MemberAt n x xs) => HasItemN' n x (Many xs) where+ itemN' = lens (fetchN @n) (replaceN' @n) --- | Polymorphic version of 'itemN'-itemN' :: forall n y xs proxy x. MemberAt n x xs => proxy n -> Lens (Many xs) (Many (ReplaceIndex n y xs)) x y-itemN' p = lens (fetchN p) (replaceN' @n @y p)+-- | Polymorphic version of 'itemN''+class HasItemN (n :: Nat) a b s t | s n -> a, t n -> b, s n b -> t, t n a -> s where+ itemN :: Lens s t a b --- | I'm using "Data.Generics" as the canoical class for HasXXX.--- Overlap 'HasPosition' 'position' with the more efficient 'itemN''--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} (MemberAt n x xs, ys ~ ReplaceIndex n y xs) =>- HasPosition n (Many xs) (Many ys) x y where- position = itemN' (Proxy @n)+ -- | Make it easy to create an instance of 'itemN' using 'Data.Generics.Product.Positions'+ default itemN :: (HasPosition n s t a b) => Lens s t a b+ itemN = position @n +instance (MemberAt n x xs, ys ~ ReplaceIndex n y xs)+ => HasItemN n x y (Many xs) (Many ys) where+ itemN = lens (fetchN @n) (replaceN @n)+ ----------------------------------------------------------------------- +-- type family Projected (xs :: k) s+-- type instance Projected xs (Many _) = Many xs+ -- | 'select' ('view' 'project') and 'amend' ('set' 'project') in 'Lens'' form. -- -- @@@ -143,65 +164,78 @@ -- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'--- x '^.' ('project' \@'[Int, Maybe Char]) \`shouldBe` (5 :: Int) './' Just \'O' './' 'nil'--- (x '&' ('project' \@'[Int, Maybe Char]) '.~' ((6 :: Int) './' Just 'P' './' 'nil')) \`shouldBe`+-- x '^.' ('project'' \@'[Int, Maybe Char]) \`shouldBe` (5 :: Int) './' Just \'O' './' 'nil'+-- (x '&' ('project'' \@'[Int, Maybe Char]) '.~' ((6 :: Int) './' Just 'P' './' 'nil')) \`shouldBe` -- (6 :: Int) './' False './' \'X' './' Just \'P' './' 'nil' -- @-project- :: forall smaller larger.- (Select smaller larger, Amend smaller larger)- => Lens' (Many larger) (Many smaller)-project = lens select amend+class HasProject' (as :: k) (ss :: k) a s | a -> as, s -> ss, s as -> a, a ss -> s where+ project' :: Lens' s a + -- | Make it easy to create an instance of 'project' using 'Data.Generics.Product.Subtype'+ default project' :: (Subtype a s) => Lens' s a+ project' = super++instance (Select smaller larger, Amend' smaller larger)+ => HasProject' smaller larger (Many smaller) (Many larger) where+ project' = lens select amend'+ -- | Polymorphic version of project'-project'- :: forall smaller smaller' larger.- (Select smaller larger, Amend' smaller smaller' larger)- => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')-project' = lens select (amend' @smaller @smaller' Proxy)+class HasProject (as :: k) (bs :: k) (ss :: k) (ts :: k) a b s t+ | a -> as, b -> bs, s -> ss, t -> ts+ , b as -> a, s as -> a, t as -> a+ , a bs -> b, s bs -> b, t bs -> b+ , a ss -> s, b ss -> s, t ss -> s+ , a ts -> t, b ts -> t, s ts -> t+ , s a b -> t, t a b -> s where+ project :: Lens s t a b --- | I'm using "Data.Generics" as the canoical class for HasXXX.--- Overlap 'Subtype' 'super' with the more efficient 'project'--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} (Select smaller larger, Amend smaller larger) =>- Subtype (Many smaller) (Many larger) where- super = project+instance (Select smaller larger, Amend smaller smaller' larger, larger' ~ Replaces smaller smaller' larger)+ => HasProject smaller smaller' larger larger' (Many smaller) (Many smaller') (Many larger) (Many larger') where+ project = lens select (amend @smaller @smaller') -- | 'selectL' ('view' 'projectL') and 'amendL' ('set' 'projectL') in 'Lens'' form. -- -- @ -- let x = False './' Tagged \@\"Hi" (5 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Bye" \'O' './' 'nil'--- x '^.' ('projectL' \@'[Foo, Bar] Proxy) \`shouldBe` Tagged \@Foo False './' Tagged \@Bar \'X' './' nil--- (x '&' ('projectL' \@'[\"Hi", \"Bye"] Proxy) '.~' (Tagged \@\"Hi" (6 :: Int) './' Tagged \@\"Bye" \'P' './' nil)) '`shouldBe`+-- x '^.' ('projectL'' \@'[Foo, Bar] Proxy) \`shouldBe` Tagged \@Foo False './' Tagged \@Bar \'X' './' nil+-- (x '&' ('projectL'' \@'[\"Hi", \"Bye"] Proxy) '.~' (Tagged \@\"Hi" (6 :: Int) './' Tagged \@\"Bye" \'P' './' nil)) '`shouldBe` -- False './' Tagged \@\"Hi" (6 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Bye" \'P' './' 'nil' -- @-projectL- :: forall ls smaller larger proxy.- ( Select smaller larger- , Amend smaller larger- , smaller ~ KindsAtLabels ls larger- , IsDistinct ls- , UniqueLabels ls larger)- => proxy ls -> Lens' (Many larger) (Many smaller)-projectL p = lens (selectL p) (amendL p)+class HasProjectL' (ls :: k1) (as :: k) (ss :: k) a s | a -> as, s -> ss, s as -> a, a ss -> s, s ls -> as where+ projectL' :: Lens' s a --- | Polymorphic version of projectL'+instance ( Select smaller larger+ , Amend' smaller larger+ , smaller ~ KindsAtLabels ls larger+ , IsDistinct ls+ , UniqueLabels ls larger) => HasProjectL' ls smaller larger (Many smaller) (Many larger) where+ projectL' = lens (selectL @ls) (amendL' @ls)++-- | Polymorphic version of 'projectL'' -- -- @ -- let x = False './' Tagged \@\"Hi" (5 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Bye" \'O' './' 'nil'--- (x '&' ('projectL'' \@'[\"Hi", \"Bye"] Proxy) '.~' (True './' Tagged \@\"Changed" False './' 'nil')) \`shouldBe`+-- (x '&' ('projectL' \@'[\"Hi", \"Bye"] Proxy) '.~' (True './' Tagged \@\"Changed" False './' 'nil')) \`shouldBe` -- False './' True './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Changed" False './' 'nil' -- @-projectL'- :: forall ls smaller smaller' larger proxy.- ( Select smaller larger- , Amend' smaller smaller' larger- , smaller ~ KindsAtLabels ls larger- , IsDistinct ls- , UniqueLabels ls larger)- => proxy ls -> Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')-projectL' p = lens (selectL p) (amendL' p)+class HasProjectL (ls :: k1) (as :: k) (bs :: k) (ss :: k) (ts :: k) a b s t+ | a -> as, b -> bs, s -> ss, t -> ts+ , b as -> a, s as -> a, t as -> a+ , a bs -> b, s bs -> b, t bs -> b+ , a ss -> s, b ss -> s, t ss -> s+ , a ts -> t, b ts -> t, s ts -> t+ , s ls -> as, t ls -> bs, s ls b -> t, t ls a -> s where+ projectL :: Lens s t a b +instance ( Select smaller larger+ , Amend smaller smaller' larger+ , smaller ~ KindsAtLabels ls larger+ , IsDistinct ls+ , UniqueLabels ls larger+ , larger' ~ Replaces smaller smaller' larger)+ => HasProjectL ls smaller smaller' larger larger' (Many smaller) (Many smaller') (Many larger) (Many larger') where+ projectL = lens (selectL @ls) (amendL @ls)+ -- | 'selectN' ('view' 'projectN') and 'amendN' ('set' 'projectN') in 'Lens'' form. -- -- @@@ -214,15 +248,23 @@ -- (x '&' ('projectN' \@'[5, 4, 0] Proxy) '.~' (Just \'B' './' (8 :: Int) './' (4 ::Int) './' nil)) \`shouldBe` -- (4 :: Int) './' False './' \'X' './' Just \'O' './' (8 :: Int) './' Just \'B' './' 'nil' -- @-projectN- :: forall ns smaller larger proxy.- (SelectN ns smaller larger, AmendN ns smaller larger)- => proxy ns -> Lens' (Many larger) (Many smaller)-projectN p = lens (selectN p) (amendN p)+class HasProjectN' (ns :: [Nat]) (as :: k) (ss :: k) a s | a -> as, s -> ss, s as -> a, a ss -> s, s ns -> as where+ projectN' :: Lens' s a --- | Polymorphic version of 'projectN'-projectN'- :: forall ns smaller smaller' larger proxy.- (SelectN ns smaller larger, AmendN' ns smaller smaller' larger)- => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller')-projectN' p = lens (selectN p) (amendN' p)+instance (SelectN ns smaller larger, AmendN' ns smaller larger)+ => HasProjectN' ns smaller larger (Many smaller) (Many larger) where+ projectN' = lens (selectN @ns) (amendN' @ns)++-- | Polymorphic version of 'projectN''+class HasProjectN (ns :: [Nat]) (as :: k) (bs :: k) (ss :: k) (ts :: k) a b s t+ | a -> as, b -> bs, s -> ss, t -> ts+ , b as -> a, s as -> a, t as -> a+ , a bs -> b, s bs -> b, t bs -> b+ , a ss -> s, b ss -> s, t ss -> s+ , a ts -> t, b ts -> t, s ts -> t+ , s ns -> as, t ns -> bs, s ns b -> t, t ns a -> s where+ projectN :: Lens s t a b++instance (SelectN ns smaller larger, AmendN ns smaller smaller' larger, larger' ~ ReplacesIndex ns smaller' larger)+ => HasProjectN ns smaller smaller' larger larger' (Many smaller) (Many smaller') (Many larger) (Many larger') where+ projectN = lens (selectN @ns) (amendN @ns)
src/Data/Diverse/Lens/Which.hs view
@@ -1,7 +1,9 @@-{-# OPTIONS_GHC -Wno-orphans #-}-+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PolyKinds #-}@@ -16,6 +18,7 @@ facet , facetL , facetTag+ , genericFacetTag , facetN -- * Multiple types@@ -28,9 +31,9 @@ import Control.Lens import Data.Diverse.Which import Data.Diverse.TypeLevel-import Data.Proxy-import Data.Tagged import Data.Generics.Sum+import Data.Tagged+import GHC.TypeLits ----------------------------------------------------------------- @@ -45,17 +48,16 @@ -- x = 'preview' ('facet' \@Int) y -- 'trial' -- x \`shouldBe` (Just 5) -- @-facet :: forall x xs. (UniqueMember x xs) => Prism' (Which xs) x-facet = prism' pick trial'+class AsFacet a s where+ facet :: Prism' s a --- | I'm using "Data.Generics" as the canoical class for AsXXX.--- Overlap 'AsType' '_Typed' with the more efficient 'facet'--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} UniqueMember x xs => AsType x (Which xs) where- _Typed = facet- injectTyped = pick- projectTyped = trial'+ -- | Make it easy to create an instance of 'AsFacet' using 'Data.Generics.Sum.Typed'+ default facet :: (AsType a s) => Prism' s a+ facet = _Typed +instance UniqueMember x xs => AsFacet x (Which xs) where+ facet = prism' pick trial'+ -- | 'pickL' ('review' 'facetL') and 'trialL'' ('preview' 'facetL'') in 'Prism'' form. -- -- @@@ -63,22 +65,24 @@ -- x = 'preview' ('facetL' \@Bar Proxy) y -- x \`shouldBe` (Just (Tagged 5)) -- @-facetL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs)- => proxy l -> Prism' (Which xs) x-facetL p = prism' (pickL p) (trialL' p)+class AsFacetL (l :: k) a s | s l -> a where+ facetL :: Prism' s a +instance (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => AsFacetL l x (Which xs) where+ facetL = prism' (pickL @l) (trialL' @l)+ -- | Variation of 'fetchL' specialized to 'Tagged' which automatically tags and untags the field.-facetTag :: forall l xs proxy x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs)- => proxy l -> Prism' (Which xs) x-facetTag p = prism' (pickTag p) (trialTag' p)+class AsFacetTag (l :: k) a s | s l -> a where+ facetTag :: Prism' s a --- | I'm using "Data.Generics" as the canoical class for AsXXX.--- Overlap 'AsConstructor' '_Ctor' with the more efficient 'facetTag'--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs)- => AsConstructor l (Which xs) (Which xs) x x where- _Ctor = facetTag (Proxy @l)+-- | Make it easy to create an instance of 'AsFacetTag' using 'Data.Generics.Sum.Constructors'+-- NB. This is not a default signature for AsFacetTag, as this makes GHC think that l must be type 'Symbol', when actually @l@ can be any kind @k@+genericFacetTag :: forall l a s proxy. (AsConstructor l s s a a) => proxy l -> Prism' s a+genericFacetTag _ = _Ctor @l +instance (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => AsFacetTag l x (Which xs) where+ facetTag = prism' (pickTag @l) (trialTag' @l)+ -- | 'pickN' ('review' 'facetN') and 'trialN' ('preview' 'facetN') in 'Prism'' form. -- -- @@@ -90,11 +94,13 @@ -- x = 'preview' ('facetN' (Proxy \@4)) y -- 'trialN' -- x \`shouldBe` (Just 5) -- @-facetN :: forall n xs proxy x. (MemberAt n x xs) => proxy n -> Prism' (Which xs) x-facetN p = prism' (pickN p) (trialN' p)+class AsFacetN (n :: Nat) a s | s n -> a where+ facetN :: Prism' s a -------------------------------------------------------------------+instance (MemberAt n x xs) => AsFacetN n x (Which xs) where+ facetN = prism' (pickN @n) (trialN' @n) +------------------------------------------------------------------ -- | 'diversify' ('review' 'inject') and 'reinterpret'' ('preview' 'inject') in 'Prism'' form. --@@ -105,24 +111,13 @@ -- let y' = 'preview' ('inject' \@[String, Int]) y -- 'reinterpret' -- y' \`shouldBe` Just (pick (5 :: Int)) :: Maybe ('Which' '[String, Int]) -- @-inject- :: forall branch tree.- ( Diversify branch tree- , Reinterpret' branch tree- )- => Prism' (Which tree) (Which branch)-inject = prism' diversify reinterpret'+class AsInject (as :: k) (ss :: k) a s | a -> as, s -> ss, s as -> a, a ss -> s where+ inject :: Prism' s a --- | I'm using "Data.Generics" as the canoical class for AsXXX.--- Overlap 'AsSubtype' '_Sub' with the more efficient 'inject'--- Undecidableinstances! Orphan instance!-instance {-# OVERLAPPING #-} (Diversify branch tree, Reinterpret' branch tree)- => AsSubtype (Which branch) (Which tree) where- _Sub = inject- injectSub = diversify- projectSub a = case reinterpret' a of- Nothing -> Left a- Just a' -> Right a'+instance ( Diversify branch tree+ , Reinterpret' branch tree+ ) => AsInject branch tree (Which branch) (Which tree) where+ inject = prism' diversify reinterpret' -- | 'diversifyL' ('review' 'injectL') and 'reinterpretL'' ('preview' 'injectL') in 'Prism'' form. --@@ -134,17 +129,17 @@ -- t \`shouldBe` t' -- b' \`shouldBe` Just b -- @-injectL- :: forall ls branch tree proxy.- ( Diversify branch tree- , Reinterpret' branch tree- , branch ~ KindsAtLabels ls tree- , UniqueLabels ls tree- , IsDistinct ls- )- => proxy ls -> Prism' (Which tree) (Which branch)-injectL p = prism' (diversifyL p) (reinterpretL' p)+class AsInjectL (ls :: k1) (as :: k) (ss :: k) a s | a -> as, s -> ss, s as -> a, a ss -> s, s ls -> as where+ injectL :: Prism' s a +instance ( Diversify branch tree+ , Reinterpret' branch tree+ , branch ~ KindsAtLabels ls tree+ , UniqueLabels ls tree+ , IsDistinct ls+ ) => AsInjectL ls branch tree (Which branch) (Which tree) where+ injectL = prism' (diversifyL @ls) (reinterpretL' @ls)+ -- | 'diversifyN' ('review' 'injectN') and 'reinterpretN'' ('preview' 'injectN') in 'Prism'' form. -- -- @@@ -154,10 +149,10 @@ -- let y' = 'preview' ('injectN' @[3, 1] \@[String, Int] Proxy) y -- 'reinterpertN'' -- y' \`shouldBe` Just ('pick' (5 :: Int)) :: Maybe ('Which' '[String, Int]) -- @-injectN- :: forall indices branch tree proxy.- ( DiversifyN indices branch tree- , ReinterpretN' indices branch tree- )- => proxy indices -> Prism' (Which tree) (Which branch)-injectN p = prism' (diversifyN p) (reinterpretN' p)+class AsInjectN (ns :: [Nat]) (as :: k) (ss :: k) a s | a -> as, s -> ss, s as -> a, a ss -> s, s ns -> as where+ injectN :: Prism' s a++instance ( DiversifyN ns branch tree+ , ReinterpretN' ns branch tree+ ) => AsInjectN ns branch tree (Which branch) (Which tree) where+ injectN = prism' (diversifyN @ns) (reinterpretN' @ns)
src/Data/Diverse/Profunctor/Many.hs view
@@ -23,7 +23,6 @@ import Data.Diverse.Many import Data.Diverse.TypeLevel import Data.Profunctor-import Data.Proxy -- | Like 'Strong' or 'Arrow' but lifting into 'Many' itemized@@ -33,7 +32,7 @@ , UniqueMember b (Replace a b a') ) => w a b -> w (Many a') (Many (Replace a b a'))-itemized w = dimap (\c -> (fetch c, c)) (\(b, c) -> replace' (Proxy @a) c b) (first' w)+itemized w = dimap (\c -> (fetch c, c)) (\(b, c) -> replace @a c b) (first' w) -- | Like 'Strong' or 'Arrow' but lifting into 'Many' of one type itemized' :: Profunctor w => w a b -> w (Many '[a]) (Many '[b])@@ -44,10 +43,10 @@ :: forall a' proxy w a b. ( Profunctor w , Strong w , Select a a'- , Amend' a b a'+ , Amend a b a' ) => proxy a' -> w (Many a) (Many b) -> w (Many a') (Many (Replaces a b a'))-projected _ w = dimap (\c -> (select c, c)) (\(b, c) -> amend' (Proxy @a) c b) (first' w)+projected _ w = dimap (\c -> (select c, c)) (\(b, c) -> amend @a c b) (first' w) -- | Split the input between the two argument arrows and combine their output. -- The type of the resultant input is a 'Many' of all the unique types in the argument arrows' inputs,
test/Data/Diverse/Lens/ManySpec.hs view
@@ -12,9 +12,7 @@ import Data.Diverse import Data.Diverse.Lens import Data.Tagged-import Data.Typeable import Test.Hspec-import Data.Generics.Product -- `main` is here so that this module can be run from GHCi on its own. It is -- not needed for automatic spec discovery.@@ -34,114 +32,85 @@ x `shouldBe` review _Many' t t `shouldBe` view _Many' x - it "has getter/setter lens using 'item'" $ do- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- x ^. item @Int `shouldBe` 5- (x & item @Int .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- x ^. item @Bool `shouldBe` False- (x & item @Bool .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nil- x ^. item @Char `shouldBe` 'X'- x ^. item @(Maybe Char) `shouldBe` Just 'O'-- it "has getter/setter lens using 'Data.Generics.typed" $ do+ it "has getter/setter lens using 'item''" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- x ^. typed @Int `shouldBe` 5- (x & typed @Int .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- x ^. typed @Bool `shouldBe` False- (x & typed @Bool .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nil- x ^. typed @Char `shouldBe` 'X'- x ^. typed @(Maybe Char) `shouldBe` Just 'O'- x ^. typed @(Maybe Char) `shouldBe` Just 'O'+ x ^. item' @Int `shouldBe` 5+ (x & item' @Int .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+ x ^. item' @Bool `shouldBe` False+ (x & item' @Bool .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nil+ x ^. item' @Char `shouldBe` 'X'+ x ^. item' @(Maybe Char) `shouldBe` Just 'O' - it "has polymorphic getter/setter lens using 'item''" $ do+ it "has polymorphic getter/setter lens using 'item'" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- (x & item' @(Maybe Char) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil- (x & item' @Int .~ 'Z') `shouldBe` 'Z' ./ False ./ 'X' ./ Just 'O' ./ nil- (x & item' @Bool .~ 'Z') `shouldBe` (5 :: Int) ./ 'Z' ./ 'X' ./ Just 'O' ./ nil- (x & item' @Char .~ True) `shouldBe` (5 :: Int) ./ False ./ True ./ Just 'O' ./ nil- (x & item' @(Maybe Char) .~ 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ 'P' ./ nil+ (x & item @(Maybe Char) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil+ (x & item @Int .~ 'Z') `shouldBe` 'Z' ./ False ./ 'X' ./ Just 'O' ./ nil+ (x & item @Bool .~ 'Z') `shouldBe` (5 :: Int) ./ 'Z' ./ 'X' ./ Just 'O' ./ nil+ (x & item @Char .~ True) `shouldBe` (5 :: Int) ./ False ./ True ./ Just 'O' ./ nil+ (x & item @(Maybe Char) .~ 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ 'P' ./ nil - it "has getter/setter lens using 'item'" $ do+ it "has getter/setter lens using 'itemL''" $ do let x = (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ nil- x ^. itemL @Foo Proxy `shouldBe` Tagged @Foo False- (x & itemL @Foo Proxy .~ Tagged @Foo True) `shouldBe` (5 :: Int) ./ Tagged @Foo True ./ Tagged @Bar 'X' ./ nil+ x ^. itemL' @Foo `shouldBe` Tagged @Foo False+ (x & itemL' @Foo .~ Tagged @Foo True) `shouldBe` (5 :: Int) ./ Tagged @Foo True ./ Tagged @Bar 'X' ./ nil - it "has polymorphic getter/setter lens using 'itemL''" $ do+ it "has polymorphic getter/setter lens using 'itemL'" $ do let x = (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ nil- (x & itemL' @Foo Proxy .~ "foo") `shouldBe` (5 :: Int) ./ "foo" ./ Tagged @Bar 'X' ./ nil-- it "has polymorphic getter/setter lens using 'Data.Generics.Product.Fields.field'" $ do- let x = (5 :: Int) ./ Tagged @"foo" False ./ Tagged @"bar" 'X' ./ nil- (x & field @"foo" .~ "foodata") `shouldBe` (5 :: Int) ./ Tagged @"foo" "foodata" ./ Tagged @"bar" 'X' ./ nil-- it "has getter/setter lens for duplicate fields using 'itemN'" $ do- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- x ^. itemN (Proxy @0) `shouldBe` 5- (x & itemN (Proxy @0) .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- x ^. itemN (Proxy @1) `shouldBe` False- (x & itemN (Proxy @1) .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- x ^. itemN (Proxy @2) `shouldBe` 'X'- (x & itemN (Proxy @2) .~ 'O') `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- x ^. itemN (Proxy @3) `shouldBe` Just 'O'- (x & itemN (Proxy @3) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nil- x ^. itemN (Proxy @4) `shouldBe` 6- (x & itemN (Proxy @4) .~ 7) `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (7 :: Int) ./ Just 'A' ./ nil- x ^. itemN (Proxy @5) `shouldBe` Just 'A'- (x & itemN (Proxy @5) .~ Just 'B') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nil+ (x & itemL @Foo .~ "foo") `shouldBe` (5 :: Int) ./ "foo" ./ Tagged @Bar 'X' ./ nil - it "has polymorphic getter/setter lens for duplicate fields using 'itemN''" $ do+ it "has getter/setter lens for duplicate fields using 'itemN''" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & itemN' (Proxy @0) .~ "Foo") `shouldBe` "Foo" ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & itemN' (Proxy @1) .~ "Foo") `shouldBe` (5 :: Int) ./ "Foo" ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & itemN' (Proxy @2) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ "Foo" ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & itemN' (Proxy @3) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ "Foo" ./ (6 :: Int) ./ Just 'A' ./ nil- (x & itemN' (Proxy @4) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ "Foo" ./ Just 'A' ./ nil- (x & itemN' (Proxy @5) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ "Foo" ./ nil+ x ^. itemN' @0 `shouldBe` 5+ (x & itemN' @0 .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+ x ^. itemN' @1 `shouldBe` False+ (x & itemN' @1 .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+ x ^. itemN' @2 `shouldBe` 'X'+ (x & itemN' @2 .~ 'O') `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+ x ^. itemN' @3 `shouldBe` Just 'O'+ (x & itemN' @3 .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nil+ x ^. itemN' @4 `shouldBe` 6+ (x & itemN' @4 .~ 7) `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (7 :: Int) ./ Just 'A' ./ nil+ x ^. itemN' @5 `shouldBe` Just 'A'+ (x & itemN' @5 .~ Just 'B') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nil - it "has polymorphic getter/setter lens for duplicate fields using 'Data.Generic.Product.Positions.position'" $ do+ it "has polymorphic getter/setter lens for duplicate fields using 'itemN'" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & position @0 .~ "Foo") `shouldBe` "Foo" ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & position @1 .~ "Foo") `shouldBe` (5 :: Int) ./ "Foo" ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & position @2 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ "Foo" ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & position @3 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ "Foo" ./ (6 :: Int) ./ Just 'A' ./ nil- (x & position @4 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ "Foo" ./ Just 'A' ./ nil- (x & position @5 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ "Foo" ./ nil-- it "has getter/setter lens for multiple fields using 'project'" $ do- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- x ^. (project @'[Int, Maybe Char]) `shouldBe` (5 :: Int) ./ Just 'O' ./ nil- (x & (project @'[Int, Maybe Char]) .~ ((6 :: Int) ./ Just 'P' ./ nil)) `shouldBe`- (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil+ (x & itemN @0 .~ "Foo") `shouldBe` "Foo" ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+ (x & itemN @1 .~ "Foo") `shouldBe` (5 :: Int) ./ "Foo" ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+ (x & itemN @2 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ "Foo" ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+ (x & itemN @3 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ "Foo" ./ (6 :: Int) ./ Just 'A' ./ nil+ (x & itemN @4 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ "Foo" ./ Just 'A' ./ nil+ (x & itemN @5 .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ "Foo" ./ nil - it "has getter/setter lens for multiple fields using 'Data.Generics.Product.Subtype.super'" $ do+ it "has getter/setter lens for multiple fields using 'project''" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- x ^. (super @(Many '[Int, Maybe Char])) `shouldBe` (5 :: Int) ./ Just 'O' ./ nil- (x & (super @(Many '[Int, Maybe Char])) .~ ((6 :: Int) ./ Just 'P' ./ nil)) `shouldBe`+ x ^. (project' @'[Int, Maybe Char]) `shouldBe` (5 :: Int) ./ Just 'O' ./ nil+ (x & (project' @'[Int, Maybe Char]) .~ ((6 :: Int) ./ Just 'P' ./ nil)) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil it "has polymorphic getter/setter lens for multiple fields using 'project'" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil- (x & (project' @'[Int, Maybe Char]) .~ ("Foo" ./ Just "Bar" ./ nil)) `shouldBe`+ (x & (project @'[Int, Maybe Char]) .~ ("Foo" ./ Just "Bar" ./ nil)) `shouldBe` "Foo" ./ False ./ 'X' ./ Just "Bar" ./ nil - it "has getter/setter lens for multiple labelled fields using 'projectL'" $ do+ it "has getter/setter lens for multiple labelled fields using 'projectL''" $ do let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil- x ^. (projectL @'[Foo, Bar] Proxy) `shouldBe` Tagged @Foo False ./ Tagged @Bar 'X' ./ nil- (x & (projectL @'["Hi", "Bye"] Proxy) .~ (Tagged @"Hi" (6 :: Int) ./ Tagged @"Bye" 'P' ./ nil)) `shouldBe`+ x ^. (projectL' @'[Foo, Bar]) `shouldBe` Tagged @Foo False ./ Tagged @Bar 'X' ./ nil+ (x & (projectL' @'["Hi", "Bye"]) .~ (Tagged @"Hi" (6 :: Int) ./ Tagged @"Bye" 'P' ./ nil)) `shouldBe` False ./ Tagged @"Hi" (6 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'P' ./ nil - it "has polymorphic getter/setter lens for multiple labelled fields using 'projectL''" $ do+ it "has polymorphic getter/setter lens for multiple labelled fields using 'project'" $ do let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil- (x & (projectL' @'["Hi", "Bye"] Proxy) .~ (True ./ Tagged @"Changed" False ./ nil)) `shouldBe`+ (x & (projectL @'["Hi", "Bye"]) .~ (True ./ Tagged @"Changed" False ./ nil)) `shouldBe` False ./ True ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Changed" False ./ nil - it "has getter/setter lens for multiple fields with duplicates using 'projectN'" $ do+ it "has getter/setter lens for multiple fields with duplicates using 'projectN''" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- x ^. (projectN @'[5, 4, 0] Proxy) `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil- (x & (projectN @'[5, 4, 0] Proxy) .~ (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nil)) `shouldBe`+ x ^. (projectN' @'[5, 4, 0]) `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil+ (x & (projectN' @'[5, 4, 0]) .~ (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nil)) `shouldBe` (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'B' ./ nil it "has polymorphic getter/setter lens for multiple fields with duplicates using 'projectN'" $ do let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil- (x & (projectN' @'[5, 4, 0] Proxy) .~ (Just "Foo" ./ (8 :: Int) ./ "Bar" ./ nil)) `shouldBe`+ (x & (projectN @'[5, 4, 0]) .~ (Just "Foo" ./ (8 :: Int) ./ "Bar" ./ nil)) `shouldBe` "Bar" ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just "Foo" ./ nil
test/Data/Diverse/Lens/WhichSpec.hs view
@@ -11,8 +11,6 @@ import Control.Lens import Data.Diverse import Data.Diverse.Lens-import Data.Generics.Sum-import Data.Proxy import Data.Tagged import Test.Hspec @@ -39,29 +37,23 @@ x = preview (facet @Int) y x `shouldBe` (Just 5) - it "can be constructed and destructed by type with 'Data.Generics.Sum.Typed._Typed'" $ do- let y = review (_Typed @Int) (5 :: Int) :: Which '[Bool, Int, Char, Bool, Char]- x = preview (_Typed @Int) y- x `shouldBe` (Just 5)- it "can be constructed and destructed by label with 'facetL'" $ do- let y = review (facetL @Bar Proxy) (Tagged (5 :: Int)) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]- x = preview (facetL @Bar Proxy) y- x `shouldBe` (Just (Tagged 5))+ let y = review (facetL @Bar) (Tagged (5 :: Int)) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]+ x = preview (facetL @Bar) y+ z = preview (facetL @Foo) y+ x `shouldBe` Just (Tagged 5)+ z `shouldBe` Nothing it "can be constructed and destructed by label with 'facetTag'" $ do- let y = review (facetTag @Bar Proxy) (5 :: Int) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]- x = preview (facetTag @Bar Proxy) y- x `shouldBe` (Just 5)-- it "can be constructed and destructed by label with 'Data.Generics.Sum.Constructors._Ctor'" $ do- let y = review (_Ctor @"Bar") (5 :: Int) :: Which '[Tagged "Foo" Bool, Tagged "Bar" Int, Char, Bool, Char]- x = preview (_Ctor @"Bar") y- x `shouldBe` (Just 5)+ let y = review (facetTag @Bar) (5 :: Int) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]+ x = preview (facetTag @Bar) y+ z = preview (facetTag @Foo) y+ x `shouldBe` Just 5+ z `shouldBe` Nothing it "can be constructed and destructed by index with 'facetN'" $ do- let y = review (facetN (Proxy @4)) (5 :: Int) :: Which '[Bool, Int, Char, Bool, Int, Char]- x = preview (facetN (Proxy @4)) y+ let y = review (facetN @4) (5 :: Int) :: Which '[Bool, Int, Char, Bool, Int, Char]+ x = preview (facetN @4) y x `shouldBe` (Just 5) it "can be 'diversify'ed and 'reinterpreted' by type with 'inject'" $ do@@ -71,24 +63,17 @@ let y' = preview (inject @[String, Int]) y y' `shouldBe` Just (pick (5 :: Int)) - it "can be 'diversify'ed and 'reinterpreted' by type with 'Data.Generics.Sum.Subtype._Sub'" $ do- let x = pick (5 :: Int) :: Which '[String, Int]- y = review (_Sub @_ @(Which [Bool, Int, Char, String])) x- y `shouldBe` pick (5 :: Int)- let y' = preview (_Sub @(Which [String, Int])) y- y' `shouldBe` Just (pick (5 :: Int))- it "can be 'diversifyL'ed and 'reinterpretedL' by label with 'injectL'" $ do let t = pick @_ @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int) b = pick @_ @'[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)- t' = review (injectL @[Foo, Bar] @_ @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] Proxy) b- b' = preview (injectL @[Foo, Bar] Proxy) t'+ t' = review (injectL @[Foo, Bar] @_ @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool]) b+ b' = preview (injectL @[Foo, Bar]) t' t `shouldBe` t' b' `shouldBe` Just b it "can be 'diversifyN'ed and 'reinterpretedN' by index with 'injectN'" $ do let x = pick (5 :: Int) :: Which '[String, Int]- y = review (injectN @[3, 1] @_ @[Bool, Int, Char, String] Proxy) x+ y = review (injectN @[3, 1] @_ @[Bool, Int, Char, String]) x y `shouldBe` pick (5 :: Int)- let y' = preview (injectN @[3, 1] @[String, Int] Proxy) y+ let y' = preview (injectN @[3, 1] @[String, Int]) y y' `shouldBe` Just (pick (5 :: Int))