{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Data.Generics.Uniplate.Typeable(
module Data.Generics.Uniplate.Operations,
module Data.Typeable,
PlateAll(..),
plate, (|+), (|-), plateProject
) where
import Control.Arrow
import Data.Generics.Uniplate.Operations
import Data.Generics.Uniplate.Internal.Utils
import Data.Generics.Str
import Data.Typeable
import Data.Ratio
instance (Typeable a, Typeable b, Uniplate b, PlateAll a b) => Biplate a b where
biplate :: a -> (Str b, Str b -> a)
biplate = forall from to.
(Typeable from, Typeable to, PlateAll from to) =>
from -> Type from to
plateMore
instance PlateAll a a => Uniplate a where
uniplate :: a -> (Str a, Str a -> a)
uniplate = forall from to. PlateAll from to => from -> Type from to
plateAll
type Type from to = (Str to, Str to -> from)
plateMore :: (Typeable from, Typeable to, PlateAll from to) => from -> Type from to
plateMore :: forall from to.
(Typeable from, Typeable to, PlateAll from to) =>
from -> Type from to
plateMore from
x = (Str to, Str to -> from)
res
where
res :: (Str to, Str to -> from)
res = case forall a. a -> a -> a
asTypeOf (forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast from
x) (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Str a -> a
strType forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst (Str to, Str to -> from)
res) of
Maybe to
Nothing -> forall from to. PlateAll from to => from -> Type from to
plateAll from
x
Just to
y -> (forall a. a -> Str a
One to
y, \(One to
y) -> forall a b. a -> b
unsafeCoerce to
y)
class PlateAll from to where
plateAll :: from -> Type from to
plate :: from -> Type from to
plate :: forall from to. from -> Type from to
plate from
x = (forall a. Str a
Zero, \Str to
_ -> from
x)
(|+) :: (Typeable item, Typeable to, PlateAll item to) => Type (item -> from) to -> item -> Type from to
|+ :: forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
(|+) (Str to
xs,Str to -> item -> from
x_) item
y = case forall from to.
(Typeable from, Typeable to, PlateAll from to) =>
from -> Type from to
plateMore item
y of
(Str to
ys,Str to -> item
y_) -> (forall a. Str a -> Str a -> Str a
Two Str to
xs Str to
ys,\(Two Str to
xs Str to
ys) -> Str to -> item -> from
x_ Str to
xs (Str to -> item
y_ Str to
ys))
(|-) :: Type (item -> from) to -> item -> Type from to
|- :: forall item from to. Type (item -> from) to -> item -> Type from to
(|-) (Str to
xs,Str to -> item -> from
x_) item
y = (Str to
xs,\Str to
xs -> Str to -> item -> from
x_ Str to
xs item
y)
plateProject :: (Typeable item, Typeable to, PlateAll item to) => (from -> item) -> (item -> from) -> from -> Type from to
plateProject :: forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
(from -> item) -> (item -> from) -> from -> Type from to
plateProject from -> item
into item -> from
outof = forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (item -> from
outof forall b c a. (b -> c) -> (a -> b) -> a -> c
. ) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall from to. PlateAll from to => from -> Type from to
plateAll forall b c a. (b -> c) -> (a -> b) -> a -> c
. from -> item
into
instance PlateAll Int to where plateAll :: Int -> Type Int to
plateAll Int
x = forall from to. from -> Type from to
plate Int
x
instance PlateAll Bool to where plateAll :: Bool -> Type Bool to
plateAll Bool
x = forall from to. from -> Type from to
plate Bool
x
instance PlateAll Char to where plateAll :: Char -> Type Char to
plateAll Char
x = forall from to. from -> Type from to
plate Char
x
instance PlateAll Integer to where plateAll :: Integer -> Type Integer to
plateAll Integer
x = forall from to. from -> Type from to
plate Integer
x
instance PlateAll Double to where plateAll :: Double -> Type Double to
plateAll Double
x = forall from to. from -> Type from to
plate Double
x
instance PlateAll Float to where plateAll :: Float -> Type Float to
plateAll Float
x = forall from to. from -> Type from to
plate Float
x
instance PlateAll () to where plateAll :: () -> Type () to
plateAll ()
x = forall from to. from -> Type from to
plate ()
x
instance (PlateAll from to, Typeable from, Typeable to, Uniplate to) => PlateAll [from] to where
plateAll :: [from] -> Type [from] to
plateAll [] = forall from to. from -> Type from to
plate []
plateAll (from
x:[from]
xs) = forall from to. from -> Type from to
plate (:) forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ from
x forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ [from]
xs
instance (PlateAll from to, Typeable from, Typeable to, Uniplate to) => PlateAll (Maybe from) to where
plateAll :: Maybe from -> Type (Maybe from) to
plateAll Maybe from
Nothing = forall from to. from -> Type from to
plate forall a. Maybe a
Nothing
plateAll (Just from
x) = forall from to. from -> Type from to
plate forall a. a -> Maybe a
Just forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ from
x
instance (PlateAll a to, Typeable a, PlateAll b to, Typeable b, Typeable to, Uniplate to) =>
PlateAll (Either a b) to where
plateAll :: Either a b -> Type (Either a b) to
plateAll (Left a
x) = forall from to. from -> Type from to
plate forall a b. a -> Either a b
Left forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ a
x
plateAll (Right b
x) = forall from to. from -> Type from to
plate forall a b. b -> Either a b
Right forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ b
x
instance (PlateAll a to, Typeable a
,PlateAll b to, Typeable b
,Typeable to, Uniplate to) =>
PlateAll (a,b) to where
plateAll :: (a, b) -> Type (a, b) to
plateAll (a
a,b
b) = forall from to. from -> Type from to
plate (,) forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ a
a forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ b
b
instance (PlateAll a to, Typeable a
,PlateAll b to, Typeable b
,PlateAll c to, Typeable c
,Typeable to, Uniplate to) =>
PlateAll (a,b,c) to where
plateAll :: (a, b, c) -> Type (a, b, c) to
plateAll (a
a,b
b,c
c) = forall from to. from -> Type from to
plate (,,) forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ a
a forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ b
b forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ c
c
instance (PlateAll a to, Typeable a
,PlateAll b to, Typeable b
,PlateAll c to, Typeable c
,PlateAll d to, Typeable d
,Typeable to, Uniplate to) =>
PlateAll (a,b,c,d) to where
plateAll :: (a, b, c, d) -> Type (a, b, c, d) to
plateAll (a
a,b
b,c
c,d
d) = forall from to. from -> Type from to
plate (,,,) forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ a
a forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ b
b forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ c
c forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ d
d
instance (PlateAll a to, Typeable a
,PlateAll b to, Typeable b
,PlateAll c to, Typeable c
,PlateAll d to, Typeable d
,PlateAll e to, Typeable e
,Typeable to, Uniplate to) =>
PlateAll (a,b,c,d,e) to where
plateAll :: (a, b, c, d, e) -> Type (a, b, c, d, e) to
plateAll (a
a,b
b,c
c,d
d,e
e) = forall from to. from -> Type from to
plate (,,,,) forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ a
a forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ b
b forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ c
c forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ d
d forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
Type (item -> from) to -> item -> Type from to
|+ e
e
instance (Integral a, PlateAll a to, Typeable a, Typeable to, Uniplate to) => PlateAll (Ratio a) to where
plateAll :: Ratio a -> Type (Ratio a) to
plateAll = forall item to from.
(Typeable item, Typeable to, PlateAll item to) =>
(from -> item) -> (item -> from) -> from -> Type from to
plateProject (\Ratio a
x -> (forall a. Ratio a -> a
numerator Ratio a
x, forall a. Ratio a -> a
denominator Ratio a
x)) (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Integral a => a -> a -> Ratio a
(%))