@@ -11,9 +11,26 @@
11{-# LANGUAGE TypeOperators #-}
11{-# LANGUAGE TypeOperators #-}
12{-# LANGUAGE UndecidableInstances #-}
12{-# LANGUAGE UndecidableInstances #-}
14+-----------------------------------------------------------------------------
16+-- Module : Data.Generics.Product.Any
17+-- Copyright : (C) 2017 Csongor Kiss
19+-- Maintainer : Csongor Kiss <kiss.csongor.kiss@gmail.com>
20+-- Stability : experimental
21+-- Portability : non-portable
23+-- Derive constructor-field-type-based prisms generically.
25+-----------------------------------------------------------------------------
14module Data.Generics.Sum.Typed
27module Data.Generics.Sum.Typed
15− ( AsType (..)
31+ AsType (..)
17 , GAsType (..)
34 , GAsType (..)
@@ -25,19 +42,58 @@ import Data.Kind
25import GHC.Generics
42import GHC.Generics
26import GHC.TypeLits
43import GHC.TypeLits
47+-- module Example where
49+-- import Data.Generics.Sum
50+-- import GHC.Generics
56+-- deriving (Generic, Show)
62+-- deriving (Generic, Show)
67+-- dog, cat, duck :: Animal
69+-- dog = Dog (MkDog "Shep" 3)
70+-- cat = Cat ("Mog", 5)
74+-- |Sums that have a constructor with a field of the given type.
28class AsType a s where
75class AsType a s where
76+ -- |A prism that projects a constructor uniquely identifiable by the type of
77+ -- its field. Compatible with the lens package's 'Control.Lens.Prism' type.
79+ -- >>> dog ^? _Typed @Dog
80+ -- Just (MkDog {name = "Shep", age = 3})
81+ -- >>> dog ^? _Typed @Cat
83+ -- >>> duck ^? _Typed @Age
29 _Typed :: Prism' s a
85 _Typed :: Prism' s a
32 ( Generic s
88 ( Generic s
33− , ErrorUnless a s (HasPartialTypeP a (Rep s))
89+ , ErrorUnlessOne a s (CountPartialType a (Rep s))
34 , GAsType (Rep s) a
90 , GAsType (Rep s) a
35 ) => AsType a s where
91 ) => AsType a s where
37 _Typed = repIso . _GTyped
93 _Typed = repIso . _GTyped
39−type family ErrorUnless (a :: Type) (s :: Type) (contains :: Bool) :: Constraint where
95+type family ErrorUnlessOne (a :: Type) (s :: Type) (count :: Count) :: Constraint where
40− ErrorUnless a s 'False
96+ ErrorUnlessOne a s 'None
41 = TypeError
97 = TypeError
42 ( 'Text "The type "
98 ( 'Text "The type "
43 ':<>: 'ShowType s
99 ':<>: 'ShowType s
@@ -45,9 +101,19 @@ type family ErrorUnless (a :: Type) (s :: Type) (contains :: Bool) :: Constraint
45 ':<>: 'ShowType a
101 ':<>: 'ShowType a
48− ErrorUnless _ _ 'True
104+ ErrorUnlessOne a s 'Multiple
108+ ':<>: 'Text " contains multiple constructors whose fields are of type "
110+ ':<>: 'Text "; the choice of constructor is thus ambiguous"
113+ ErrorUnlessOne _ _ 'One
116+-- |As 'AsType' but over generic representations as defined by "GHC.Generics".
51class GAsType (f :: Type -> Type) a where
117class GAsType (f :: Type -> Type) a where
52 _GTyped :: Prism' (f x) a
118 _GTyped :: Prism' (f x) a