{-# LANGUAGE ViewPatterns #-}

module Data.Generics.Any.Prelude where

import Data.Generics.Any
import Data.Maybe


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

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

just_ :: AnyT (Maybe a) -> AnyT a -> AnyT (Maybe a)
just_ :: forall a. 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_ :: forall a. 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_ :: forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
list_ AnyT [a]
w AnyT [a]
x = forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
cons AnyT [a]
x forall a b. (a -> b) -> a -> b
$ forall a. AnyT [a] -> AnyT [a]
nil_ AnyT [a]
w

append :: AnyT [a] -> AnyT [a] -> AnyT [a]
append :: forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
append AnyT [a]
x AnyT [a]
y | AnyT [a] -> TypeRep
typeOf AnyT [a]
x forall a. Eq a => a -> a -> Bool
== AnyT [a] -> TypeRep
typeOf AnyT [a]
y = 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 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) -> forall a. AnyT [a] -> AnyT [a] -> AnyT [a]
cons AnyT [a]
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 :: forall a. AnyT [a] -> AnyT [a]
reverse AnyT [a]
xs | AnyT [a] -> Bool
isList AnyT [a]
xs = forall {a} a. AnyT [a] -> AnyT [a] -> AnyT [a]
rev AnyT [a]
xs (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 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 (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 forall a. Eq a => a -> a -> Bool
== CtorName
"[Char]"
-- GHC 9.6 changes from [] to List, so accept either
isList :: AnyT [a] -> Bool
isList AnyT [a]
x = CtorName
ts forall a. Eq a => a -> a -> Bool
== CtorName
"[]" Bool -> Bool -> Bool
|| CtorName
ts forall a. Eq a => a -> a -> Bool
== CtorName
"List"
    where ts :: CtorName
ts = AnyT [a] -> CtorName
typeShell AnyT [a]
x
isMaybe :: AnyT [a] -> Bool
isMaybe AnyT [a]
x = AnyT [a] -> CtorName
typeShell AnyT [a]
x forall a. Eq a => a -> a -> Bool
== CtorName
"Maybe"
isTuple :: AnyT [a] -> Bool
isTuple AnyT [a]
x = forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ CtorName -> Maybe Int
readTupleType 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
"(:)") 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") 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 forall a b. (a -> b) -> a -> b
$ AnyT [a] -> CtorName
typeShell AnyT [a]
w)

unit :: AnyT ()
unit :: AnyT [a]
unit = 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] = forall a. Data a => a -> AnyT [a]
Any (a
x1,a
x2)
tuple [Any a
x1,Any a
x2,Any a
x3] = 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] = 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] = 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] = 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] = 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]]
_ = forall a. HasCallStack => CtorName -> a
error CtorName
"Data.Generics.Any: Tuples of 8 elements or more are not supported by Data.Data"