Skip to content

Instantly share code, notes, and snippets.

@myuon
Created December 24, 2014 05:35
Show Gist options
  • Save myuon/afb273f341d1062f74f0 to your computer and use it in GitHub Desktop.
Save myuon/afb273f341d1062f74f0 to your computer and use it in GitHub Desktop.
{-# LANGUAGE GADTs, KindSignatures, DataKinds, FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts, RankNTypes, ConstraintKinds #-}
import GHC.TypeLits
import GHC.Prim (Constraint)
import Control.Monad.State
data SList (k :: Symbol -> Constraint) (a :: Symbol -> *) where
Nil :: SList k a
Cons :: k s => a s -> SList k a -> SList k a
lengthS :: SList k a -> Int
lengthS Nil = 0
lengthS (Cons x xs) = 1 + lengthS xs
forS_ :: (Monad m) => SList k a -> (forall s. k s => a s -> m ()) -> m ()
forS_ Nil _ = return ()
forS_ (Cons x xs) f = f x >> forS_ xs f
data Enemy (s :: Symbol) = Enemy {
pos :: (Int,Int)
} deriving (Show)
data Field = Field {
label :: String,
enemy :: SList Danmaku Enemy
}
instance Show Field where
show (Field label enemy) = "Field{label = " ++ show label ++ ", enemy : " ++ show (lengthS enemy) ++ "}"
runField :: Field -> IO Field
runField f = execStateT (forS_ (enemy f) run) f
class Danmaku s where
run :: Enemy s -> StateT Field IO ()
instance Danmaku "zako1" where
run (Enemy pos) = do
lift $ putStrLn "> zako1"
modify $ (\f -> f { label = "now at " ++ show pos })
main = do
let f = Field "" (Cons (Enemy (0,0) :: Enemy "zako1") Nil)
print $ f
print =<< runField f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment