{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Foreign.C.Struct.Ord where

import Language.Haskell.TH

compareAllMember :: [ExpQ] -> ExpQ -> ExpQ -> ExpQ
compareAllMember :: [ExpQ] -> ExpQ -> ExpQ -> ExpQ
compareAllMember [ExpQ]
ms ExpQ
x ExpQ
y = [ExpQ] -> [ExpQ] -> ExpQ
compareAllFoo ((forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ExpQ
x) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ExpQ]
ms) ((forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ExpQ
y) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ExpQ]
ms)

compareAllFoo :: [ExpQ] -> [ExpQ] -> ExpQ
compareAllFoo :: [ExpQ] -> [ExpQ] -> ExpQ
compareAllFoo [ExpQ]
xs [ExpQ]
ys = do
	Name
cr <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"checkResult"
	forall (m :: * -> *). Quote m => [m Dec] -> m Exp -> m Exp
letE [forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Dec
valD (forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
cr) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB forall a b. (a -> b) -> a -> b
$ Name -> ExpQ
checkResultFoo' Name
cr) []]
		(forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
cr forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([ExpQ] -> [ExpQ] -> ExpQ
compareList [ExpQ]
xs [ExpQ]
ys))

compareList :: [ExpQ] -> [ExpQ] -> ExpQ
compareList :: [ExpQ] -> [ExpQ] -> ExpQ
compareList [ExpQ]
xs [ExpQ]
ys = forall (m :: * -> *). Quote m => [m Exp] -> m Exp
listE forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ExpQ -> ExpQ -> ExpQ
compare' [ExpQ]
xs [ExpQ]
ys

compare' :: ExpQ -> ExpQ -> ExpQ
compare' :: ExpQ -> ExpQ -> ExpQ
compare' ExpQ
x ExpQ
y = forall (m :: * -> *). Quote m => Name -> m Exp
varE 'compare forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ExpQ
x forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ExpQ
y

checkResultFoo' :: Name -> ExpQ
checkResultFoo' :: Name -> ExpQ
checkResultFoo' Name
fn = do
	Name
x <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"x"
	Name
xs <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"xs"
	forall (m :: * -> *). Quote m => [m Match] -> m Exp
lamCaseE forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}. Quote m => Name -> Name -> Name -> [m Match]
checkResultFooLamCase Name
x Name
xs Name
fn
	where
	checkResultFooLamCase :: Name -> Name -> Name -> [m Match]
checkResultFooLamCase Name
x Name
xs Name
fn = [
		forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP '[] []) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Quote m => Name -> m Exp
conE 'True) [],
		forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (m :: * -> *). Quote m => m Pat -> Name -> m Pat -> m Pat
infixP (forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
x) '(:) (forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
xs)) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}. Quote m => Name -> Name -> Name -> m Exp
checkResultFooLamCaseCase Name
x Name
xs Name
fn) [] ]
	checkResultFooLamCaseCase :: Name -> Name -> Name -> m Exp
checkResultFooLamCaseCase Name
x Name
xs Name
fn = forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
x) [
		forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'LT []) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Quote m => Name -> m Exp
conE 'True) [],
		forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'GT []) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Quote m => Name -> m Exp
conE 'False) [],
		forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'EQ []) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
fn forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
xs) [] ]

tx, ty, tz, tw :: ExpQ
[ExpQ
tx, ExpQ
ty, ExpQ
tz, ExpQ
tw] = forall (m :: * -> *). Quote m => Name -> m Exp
varE forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Name
mkName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String
"x", String
"y", String
"z", String
"w"]

{-
letFoo = [e| let x = 8 in x |]
-}

{-
some (a, b, c) (d, e, f) =
	[a `compare` d, b `compare` e, c `compare` f]

checkResult [] = True
checkResult (x : xs) = case x of
	LT -> True
	GT -> False
	EQ -> checkResult xs

compareAll x y = checkResult $ some x y

someFoo = [d|
	some (a, b, c) (d, e, f) =
		[compare a d, compare b e, compare c f] |]

checkResultFoo = head <$> [d|
	checkResult = \case
		[] -> True
		x : xs -> case x of
			LT -> True
			GT -> False
			EQ -> checkResult xs |]
-}