module Data.Origami.Internal.FoldFamily(
FoldFamily(..),
DataTy(..),
DataCase(..),
DataField(..),
Ty(..),
HasName(..),
dataCases,
dataFields,
dataTys,
_Atomic,
_Nonatomic,
_Funct,
_Bifunct,
_Trifunct,
) where
import Control.Lens
import Data.Data
import Language.Haskell.TH
newtype FoldFamily = FoldFamily [DataTy]
deriving (Eq, Ord, Show, Data, Typeable)
data DataTy = DataTy Name [DataCase]
deriving (Eq, Ord, Show, Data, Typeable)
data DataCase = DataCase Name [DataField]
deriving (Eq, Ord, Show, Data, Typeable)
data DataField = Atomic Ty
| Nonatomic Ty
| Funct Name DataField
| Bifunct Name DataField DataField
| Trifunct Name DataField DataField DataField
deriving (Eq, Ord, Show, Data, Typeable)
newtype Ty = Ty Name
deriving (Eq, Ord, Show, Data, Typeable)
class HasName d where
name :: Lens' d Name
dataTys :: Iso' FoldFamily [DataTy]
dataTys = iso (\ (FoldFamily dts) -> dts) FoldFamily
instance HasName DataTy where
name = lens (\ (DataTy nm _) -> nm) (\ (DataTy _ dcs) nm -> DataTy nm dcs)
dataCases :: Lens' DataTy [DataCase]
dataCases = lens (\ (DataTy _ dcs) -> dcs)
(\ (DataTy nm _) dcs -> DataTy nm dcs)
instance HasName DataCase where
name = lens (\ (DataCase nm _) -> nm)
(\ (DataCase _ dfs) nm -> DataCase nm dfs)
dataFields :: Lens' DataCase [DataField]
dataFields = lens (\ (DataCase _ dfs) -> dfs)
(\ (DataCase nm _) dfs -> DataCase nm dfs)
_Atomic :: Prism' DataField Ty
_Atomic = prism Atomic (\ df -> case df of
Atomic ty -> Right ty
_ -> Left df)
_Nonatomic :: Prism' DataField Ty
_Nonatomic = prism Nonatomic (\ df -> case df of
Nonatomic ty -> Right ty
_ -> Left df)
_Funct :: Prism' DataField (Name, DataField)
_Funct = prism (uncurry Funct)
( \ df -> case df of
Funct nm df' -> Right (nm, df')
_ -> Left df)
_Bifunct :: Prism' DataField (Name, DataField, DataField)
_Bifunct = prism (\ (nm, df, df') -> Bifunct nm df df')
(\ df -> case df of
Bifunct nm df' df'' -> Right (nm, df', df'')
_ -> Left df)
_Trifunct :: Prism' DataField (Name, DataField, DataField, DataField)
_Trifunct = prism (\ (nm, df, df', df'') -> Trifunct nm df df' df'')
(\ df -> case df of
Trifunct nm df' df'' df'''
-> Right (nm, df', df'', df''')
_ -> Left df)
instance HasName Ty where
name = lens (\ (Ty nm) -> nm) (\ (Ty _) nm ->Ty nm)