{-# LANGUAGE TypeFamilies, TemplateHaskell, EmptyDataDecls, TypeOperators #-} {- | Module : Type.Spine Copyright : (c) The University of Kansas 2011 License : BSD3 Maintainer : nicolas.frisby@gmail.com Stability : experimental Portability : see LANGUAGE pragmas (... GHC) The spine-view on types. -} 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|...|]@ is the a type that takes one parameter of the corresponding -- kind. (The name is an encoding of that parameter's kind based on prefix -- notation for application.) qK :: QuasiQuoter qK = QuasiQuoter (error "Type.Spine.qK Exp") (error "Type.Spine.qK Pat") (kTypeG <=< parseK_) (error "Type.Spine.qK Dec") infixl 9 :@ -- | A type-level application. 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]