module Type.Spine (qK, Spine, TypeName, (:@), spineType) where
import Type.Spine.Kinds (parseK_, forallAppsK)
import Type.Spine.Stage0
import Language.Haskell.TH (Kind(ArrowK), tySynInstD, varT, mkName)
import Language.Haskell.TH.Quote (QuasiQuoter(..))
import Control.Monad ((<=<))
qK :: QuasiQuoter
qK = QuasiQuoter (error "Type.Spine.qK Exp")
(error "Type.Spine.qK Pat")
(kTypeG <=< parseK_) (error "Type.Spine.qK Dec")
infixl 9 :@
data tc :@ t
fmap concat $ forallAppsK $ \ak k ->
let kq = kTypeG k; aq = kTypeG ak; fq = kTypeG $ ArrowK ak k
[f, a] = map (varT . mkName) ["f", "a"]
in (:[]) `fmap` tySynInstD ''Spine [[t| $kq ($f $a) |]] [t| $fq $f :@ $aq $a |]
fmap concat $ mapM spineType
[''Bool, ''Char, ''Double, ''Float, ''Int, ''Integer, ''Ordering,
''(), ''(,), ''(,,), ''(,,,), ''(,,,,),
''IO, ''[], ''Maybe, ''(->), ''Either]