{-# 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 -> (CtorName
"(:)",[AnyT [a]
x,AnyT [a]
_])) = AnyT [a]
x

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

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

uncons :: AnyT [a] -> Maybe (AnyT a, AnyT [a])
uncons :: AnyT [a] -> Maybe (AnyT [a], AnyT [a])
uncons AnyT [a]
x = case AnyT [a] -> (CtorName, [AnyT [a]])
decompose AnyT [a]
x of
    (CtorName
"[]",[]) -> Maybe (AnyT [a], AnyT [a])
forall a. Maybe a
Nothing
    (CtorName
"(:)",[AnyT [a]
a,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 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
== CtorName
"[]"

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

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

list_ :: AnyT [a] -> AnyT a -> AnyT [a]
list_ :: AnyT [a] -> AnyT [a] -> AnyT [a]
list_ AnyT [a]
w 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 AnyT [a]
x 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 AnyT [a]
x 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
                       Maybe (AnyT [a], AnyT [a])
Nothing -> AnyT [a]
y
                       Just (AnyT [a]
a,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 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 AnyT [a]
xs 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
                           Maybe (AnyT [a], AnyT [a])
Nothing -> AnyT [a]
acc
                           Just (AnyT [a]
x,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 AnyT [a]
x = AnyT [a] -> CtorName
typeName AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== CtorName
"[Char]"
isList :: AnyT [a] -> Bool
isList AnyT [a]
x = AnyT [a] -> CtorName
typeShell AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== CtorName
"[]"
isMaybe :: AnyT [a] -> Bool
isMaybe AnyT [a]
x = AnyT [a] -> CtorName
typeShell AnyT [a]
x CtorName -> CtorName -> Bool
forall a. Eq a => a -> a -> Bool
== CtorName
"Maybe"
isTuple :: AnyT [a] -> Bool
isTuple 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 AnyT [a]
w = AnyT [a] -> [AnyT [a]]
children (AnyT [a] -> CtorName -> AnyT [a]
compose0 AnyT [a]
w CtorName
"(:)") [AnyT [a]] -> Int -> AnyT [a]
forall a. [a] -> Int -> a
!! Int
0
fromMaybe :: AnyT [a] -> AnyT [a]
fromMaybe AnyT [a]
w = AnyT [a] -> [AnyT [a]]
children (AnyT [a] -> CtorName -> AnyT [a]
compose0 AnyT [a]
w CtorName
"Just") [AnyT [a]] -> Int -> AnyT [a]
forall a. [a] -> Int -> a
!! Int
0
fromTuple :: AnyT [a] -> [AnyT [a]]
fromTuple 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 [AnyT [a]
x] = AnyT [a]
x
-- $(2\7 tuple [$(1,$ Any x$)] = Any ($(1,$ x$)))
tuple [Any a
x1,Any a
x2] = (a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2)
tuple [Any a
x1,Any a
x2,Any a
x3] = (a, a, a) -> AnyT [a]
forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2,a
x3)
tuple [Any a
x1,Any a
x2,Any a
x3,Any 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 a
x1,Any a
x2,Any a
x3,Any a
x4,Any 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 a
x1,Any a
x2,Any a
x3,Any a
x4,Any a
x5,Any 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 a
x1,Any a
x2,Any a
x3,Any a
x4,Any a
x5,Any a
x6,Any 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 [AnyT [a]]
_ = CtorName -> AnyT [a]
forall a. HasCallStack => CtorName -> a
error CtorName
"Data.Generics.Any: Tuples of 8 elements or more are not supported by Data.Data"