{-# LANGUAGE ViewPatterns #-}

module Data.Generics.Any.Prelude where

import Data.Generics.Any
import Data.Maybe


head :: AnyT [a] -> AnyT a
head :: AnyT [a] -> AnyT [a]
head (AnyT [a] -> (CtorName, [AnyT [a]])
decompose -> ("(:)",[x :: AnyT [a]
x,_])) = AnyT [a]
x

tail :: AnyT [a] -> AnyT [a]
tail :: AnyT [a] -> AnyT [a]
tail (AnyT [a] -> (CtorName, [AnyT [a]])
decompose -> ("(:)",[_,x :: AnyT [a]
x])) = AnyT [a]
x

cons :: AnyT a -> AnyT [a] -> AnyT [a]
cons :: AnyT [a] -> AnyT [a] -> AnyT [a]
cons x :: AnyT [a]
x y :: AnyT [a]
y = AnyT [a] -> CtorName -> [AnyT [a]] -> AnyT [a]
compose AnyT [a]
y "(:)" [AnyT [a]
x,AnyT [a]
y]

uncons :: AnyT [a] -> Maybe (AnyT a, AnyT [a])
uncons :: AnyT [a] -> Maybe (AnyT [a], AnyT [a])
uncons x :: AnyT [a]
x = case AnyT [a] -> (CtorName, [AnyT [a]])
decompose AnyT [a]
x of
    ("[]",[]) -> Maybe (AnyT [a], AnyT [a])
forall a. Maybe a
Nothing
    ("(:)",[a :: AnyT [a]
a,b :: AnyT [a]
b]) -> (AnyT [a], AnyT [a]) -> Maybe (AnyT [a], AnyT [a])
forall a. a -> Maybe a
Just (AnyT [a]
a,AnyT [a]
b)

null :: AnyT [a] -> Bool
null :: AnyT [a] -> Bool
null x :: AnyT [a]
x | AnyT [a] -> Bool
isList AnyT [a]
x = AnyT [a] -> CtorName
ctor AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== "[]"

just_ :: AnyT (Maybe a) -> AnyT a -> AnyT (Maybe a)
just_ :: AnyT [a] -> AnyT [a] -> AnyT [a]
just_ w :: AnyT [a]
w x :: AnyT [a]
x = AnyT [a] -> CtorName -> [AnyT [a]] -> AnyT [a]
compose AnyT [a]
w "Just" [AnyT [a]
x]

nil_ :: AnyT [a] -> AnyT [a]
nil_ :: AnyT [a] -> AnyT [a]
nil_ w :: AnyT [a]
w = AnyT [a] -> CtorName -> [AnyT [a]] -> AnyT [a]
compose AnyT [a]
w "[]" []

list_ :: AnyT [a] -> AnyT a -> AnyT [a]
list_ :: AnyT [a] -> AnyT [a] -> AnyT [a]
list_ w :: AnyT [a]
w x :: AnyT [a]
x = AnyT [a] -> AnyT [a] -> AnyT [a]
forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
cons AnyT [a]
x (AnyT [a] -> AnyT [a]) -> AnyT [a] -> AnyT [a]
forall a b. (a -> b) -> a -> b
$ AnyT [a] -> AnyT [a]
forall a. AnyT [a] -> AnyT [a]
nil_ AnyT [a]
w

append :: AnyT [a] -> AnyT [a] -> AnyT [a]
append :: AnyT [a] -> AnyT [a] -> AnyT [a]
append x :: AnyT [a]
x y :: AnyT [a]
y | AnyT [a] -> TypeRep
typeOf AnyT [a]
x TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== AnyT [a] -> TypeRep
typeOf AnyT [a]
y = AnyT [a] -> AnyT [a] -> AnyT [a]
forall a a. AnyT [a] -> AnyT [a] -> AnyT [a]
f AnyT [a]
x AnyT [a]
y
    where f :: AnyT [a] -> AnyT [a] -> AnyT [a]
f x :: AnyT [a]
x y :: AnyT [a]
y = case AnyT [a] -> Maybe (AnyT [a], AnyT [a])
forall a. AnyT [a] -> Maybe (AnyT [a], AnyT [a])
uncons AnyT [a]
x of
                       Nothing -> AnyT [a]
y
                       Just (a :: AnyT [a]
a,b :: AnyT [a]
b) -> AnyT [a] -> AnyT [a] -> AnyT [a]
forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
cons AnyT [a]
a (AnyT [a] -> AnyT [a]) -> AnyT [a] -> AnyT [a]
forall a b. (a -> b) -> a -> b
$ AnyT [a] -> AnyT [a] -> AnyT [a]
f AnyT [a]
b AnyT [a]
y

reverse :: AnyT [a] -> AnyT [a]
reverse :: AnyT [a] -> AnyT [a]
reverse xs :: AnyT [a]
xs | AnyT [a] -> Bool
isList AnyT [a]
xs = AnyT [a] -> AnyT [a] -> AnyT [a]
forall a a. AnyT [a] -> AnyT [a] -> AnyT [a]
rev AnyT [a]
xs (AnyT [a] -> AnyT [a]
forall a. AnyT [a] -> AnyT [a]
nil_ AnyT [a]
xs)
    where rev :: AnyT [a] -> AnyT [a] -> AnyT [a]
rev xs :: AnyT [a]
xs acc :: AnyT [a]
acc = case AnyT [a] -> Maybe (AnyT [a], AnyT [a])
forall a. AnyT [a] -> Maybe (AnyT [a], AnyT [a])
uncons AnyT [a]
xs of
                           Nothing -> AnyT [a]
acc
                           Just (x :: AnyT [a]
x,xs :: AnyT [a]
xs) -> AnyT [a] -> AnyT [a] -> AnyT [a]
rev AnyT [a]
xs (AnyT [a] -> AnyT [a] -> AnyT [a]
forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
cons AnyT [a]
x AnyT [a]
acc)


isString :: AnyT [a] -> Bool
isString x :: AnyT [a]
x = AnyT [a] -> CtorName
typeName AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== "[Char]"
isList :: AnyT [a] -> Bool
isList x :: AnyT [a]
x = AnyT [a] -> CtorName
typeShell AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== "[]"
isMaybe :: AnyT [a] -> Bool
isMaybe x :: AnyT [a]
x = AnyT [a] -> CtorName
typeShell AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== "Maybe"
isTuple :: AnyT [a] -> Bool
isTuple x :: AnyT [a]
x = Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Int -> Bool) -> Maybe Int -> Bool
forall a b. (a -> b) -> a -> b
$ CtorName -> Maybe Int
readTupleType (CtorName -> Maybe Int) -> CtorName -> Maybe Int
forall a b. (a -> b) -> a -> b
$ AnyT [a] -> CtorName
typeShell AnyT [a]
x

fromList :: AnyT [a] -> AnyT [a]
fromList w :: AnyT [a]
w = AnyT [a] -> [AnyT [a]]
children (AnyT [a] -> CtorName -> AnyT [a]
compose0 AnyT [a]
w "(:)") [AnyT [a]] -> Int -> AnyT [a]
forall a. [a] -> Int -> a
!! 0
fromMaybe :: AnyT [a] -> AnyT [a]
fromMaybe w :: AnyT [a]
w = AnyT [a] -> [AnyT [a]]
children (AnyT [a] -> CtorName -> AnyT [a]
compose0 AnyT [a]
w "Just") [AnyT [a]] -> Int -> AnyT [a]
forall a. [a] -> Int -> a
!! 0
fromTuple :: AnyT [a] -> [AnyT [a]]
fromTuple w :: AnyT [a]
w = AnyT [a] -> [AnyT [a]]
children (AnyT [a] -> CtorName -> AnyT [a]
compose0 AnyT [a]
w (CtorName -> AnyT [a]) -> CtorName -> AnyT [a]
forall a b. (a -> b) -> a -> b
$ AnyT [a] -> CtorName
typeShell AnyT [a]
w)

unit :: AnyT ()
unit :: AnyT [a]
unit = () -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any ()

-- Could use a witness and avoid switching on the list of tuples, but this
-- presents a nicer interface
tuple :: [Any] -> Any
tuple :: [AnyT [a]] -> AnyT [a]
tuple [] = AnyT [a]
unit
tuple [x :: AnyT [a]
x] = AnyT [a]
x
-- $(2\7 tuple [$(1,$ Any x$)] = Any ($(1,$ x$)))
tuple [Any x1 :: a
x1,Any x2 :: a
x2] = (a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2)
tuple [Any x1 :: a
x1,Any x2 :: a
x2,Any x3 :: a
x3] = (a, a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2,a
x3)
tuple [Any x1 :: a
x1,Any x2 :: a
x2,Any x3 :: a
x3,Any x4 :: a
x4] = (a, a, a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2,a
x3,a
x4)
tuple [Any x1 :: a
x1,Any x2 :: a
x2,Any x3 :: a
x3,Any x4 :: a
x4,Any x5 :: a
x5] = (a, a, a, a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2,a
x3,a
x4,a
x5)
tuple [Any x1 :: a
x1,Any x2 :: a
x2,Any x3 :: a
x3,Any x4 :: a
x4,Any x5 :: a
x5,Any x6 :: a
x6] = (a, a, a, a, a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2,a
x3,a
x4,a
x5,a
x6)
tuple [Any x1 :: a
x1,Any x2 :: a
x2,Any x3 :: a
x3,Any x4 :: a
x4,Any x5 :: a
x5,Any x6 :: a
x6,Any x7 :: a
x7] = (a, a, a, a, a, a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2,a
x3,a
x4,a
x5,a
x6,a
x7)
tuple _ = CtorName -> AnyT [a]
forall a. HasCallStack => CtorName -> a
error "Data.Generics.Any: Tuples of 8 elements or more are not supported by Data.Data"