module Guess.Combinator (combinator) where
import Guess.Combinator.Lib
combinator ∷ GuessCombinator t HNil ⇒ t
combinator = combinatorWith emptyEnv
test =
((combinator ∷ a → (a → b) → b) 'O' (:"K"), "OK")
.*. (combinator 'O' (:"K") :: String, "OK")
.*. ((combinator ∷ a → (a → b) → b) 1 (+2), 3)
.*. ((combinator ∷ (b → c) → (a → b) → a → c) Just Right True, Just (Right True))
.*. ((combinator ∷ a → b → a) 'a' 'b', 'a')
.*. ((combinator ∷ (t → t1) → t → t2 → t1) Just 1 'c', Just 1)
.*. ((combinator ∷ (b → c) → (a → b) → a → c) (:[]) ((,) True) 10, [(True, 10)])
.*. ((combinator ∷ (((a → b → c) → (a → b) → a → c)→ (t3 → t1 → t2 → t3) → t) → t) (\f g → f (g 1) (:[]) 2), 1)
.*. ((combinator ∷ ((a → b) → c) → (a → b) → c) ($2) (+3), 5)
.*. (combinator 'a' True ∷ Bool, True)
.*. HNil
newtype TypeToTermT tl t = TypeToTermT t deriving Show
class GuessCombinator t env where
combinatorWith ∷ env → t
instance (IsFunction t flag,
GuessWith' flag t env)
⇒ GuessCombinator t env where
combinatorWith = guessWith' (Proxy ∷ Proxy flag)
class GuessWith' flag t env where
guessWith' ∷ (Proxy flag) → env → t
instance (IsFunction x flagx,
FunToList' flagx x tlx,
IsFunction y flagy,
GuessWith' flagy y ((TypeToTermT tlx x) :*: env))
⇒ GuessWith' HTrue (x → y) env where
guessWith' _ env = \(v ∷ x) →
guessWith' (Proxy ∷ Proxy flagy) (((TypeToTermT v) ∷ TypeToTermT tlx x) .*. env)
instance (RResolve env ((t :*: HNil) :*: HNil) HNil t)
⇒ GuessWith' HFalse t env where
guessWith' _ env = rresolve env (Proxy ∷ Proxy ((t :*: HNil) :*: HNil)) HNil
class RResolve env goals tl t | env goals tl → t where
rresolve ∷ env → (Proxy goals) → tl → t
instance RResolve env HNil (t :*: HNil) t where
rresolve _ _ (HCons t HNil) = t
instance RResolve env HNil (t1 :*: tr) (t→r)
⇒ RResolve env HNil (t :*: t1 :*: tr) r where
rresolve g _ (HCons t r) = (rresolve g (Proxy ∷ Proxy HNil) r) t
instance (RHLookup g env (TypeToTermT (g :*: assum) g'),
HReverse assum assum',
RResolve env assum' (g' :*: HNil) ra,
RResolve env gr (ra :*: pt) t)
⇒ RResolve env ((g :*: HNil) :*: gr) pt t where
rresolve env _ pt = rresolve env (Proxy ∷ Proxy gr) (ra .*. pt)
where
TypeToTermT t1 = rhlookup (Proxy ∷ Proxy g) env
ra ∷ ra = rresolve env (Proxy ∷ Proxy assum') (t1 .*. HNil)
instance (HReverse (gc :*: gcr) revr,
ExtendEnv env revr ra env' f,
RResolve env' ((g :*: HNil) :*: HNil) HNil ra,
RResolve env gr (f :*: pt) t)
⇒ RResolve env ((g :*: gc :*: gcr) :*: gr) pt t where
rresolve (env ∷ env) _ (pt ∷ pt) = rresolve env (Proxy ∷ Proxy gr) (f .*. pt)
where
f ∷ f
f = extendEnv env (Proxy ∷ Proxy revr) $ \(env' ∷ env') →
rresolve env' (Proxy ∷ Proxy ((g :*: HNil) :*: HNil)) HNil
class ExtendEnv env vs ret env' fun | env vs ret → env' fun where
extendEnv ∷ env → (Proxy vs) → (env' → ret) → fun
instance ExtendEnv env HNil ret env ret where
extendEnv env _ k = k env
instance
(ExtendEnv env rest ret env' fun,
ListToFun pt t)
⇒ ExtendEnv env (pt :*: rest) ret ((TypeToTermT pt t) :*: env') (t → fun)
where
extendEnv env _ f = \(t ∷ t) →
extendEnv env (Proxy ∷ Proxy rest) $ \env' →
f ((TypeToTermT t ∷ TypeToTermT pt t) .*. env')
class RHLookup t l w | t l → w where
rhlookup ∷ (Proxy t) → l → w
instance (TypeEq t t' flag, RHLookup' flag t ((TypeToTermT (t' :*: at) tt') :*: r) w)
⇒ RHLookup t ((TypeToTermT (t' :*: at) tt') :*: r) w where
rhlookup = rhlookup' (Proxy ∷ Proxy flag)
class RHLookup' flag t l w | flag t l → w where
rhlookup' ∷ (Proxy flag) → (Proxy t) → l → w
instance RHLookup' HTrue t ((TypeToTermT (t :*: at) tt) :*: r)
(TypeToTermT (t :*: at) tt) where
rhlookup' _ _ (HCons t _) = t
instance RHLookup t r w ⇒ RHLookup' HFalse t ((TypeToTermT tl' t') :*: r) w where
rhlookup' _ t (HCons _ r) = rhlookup t r
emptyEnv = HNil
consEnv ∷ FunToList t tl ⇒ t → env → TypeToTermT tl t :*: env
consEnv x env = TypeToTermT x .*. env