{-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE KindSignatures #-} -- from https://ocharles.org.uk/blog/guest-posts/2014-12-18-rank-n-types.html import System.Random import Control.Monad.State import Data.Char id' :: forall a. a -> a id' x = x f = print (id' (3 :: Integer), id' "blah") -- rank 2 polymorphism type IdFunc = forall a. a -> a id'' :: IdFunc id'' x = x someInt :: IdFunc -> Integer someInt id' = id' 3 -- rank 3 polymorphism type SomeInt = IdFunc -> Integer someOtherInt :: SomeInt -> Integer someOtherInt someInt' = someInt' id + someInt' id -- random numbers data Player = Player { playerName :: String, playerPos :: (Double, Double) } deriving (Eq, Ord, Show) {- randomPlayer :: (MonadIO m, MonadState g m, RandomGen g) => m Player -} type GenAction m = forall a. (Random a) => m a type GenActionR m = forall a. (Random a) => (a, a) -> m a -- genRandom :: (RandomGen g) => GenAction (State g) -- genRandom = state random genRandomR :: (RandomGen g) => GenActionR (State g) genRandomR range = state (randomR range) genRandom :: (Random a, RandomGen g) => State g a genRandom = state random randomPlayer :: (MonadIO m) => GenActionR m -> m Player randomPlayer genR = do liftIO (putStrLn "Generating random player...") len <- genR (8, 12) name <- replicateM len (genR ('a', 'z')) x <- genR (-100, 100) y <- genR (-100, 100) liftIO (putStrLn "Done.") return (Player name (x, y)) main :: IO () main = randomPlayer randomRIO >>= print -- scott encoding data List a = Cons a (List a) | Nil uncons :: (a -> List a -> r) -> r -> List a -> r uncons co ni (Cons x xs) = co x xs uncons co ni Nil = ni listNull :: List a -> Bool listNull = uncons (\_ _ -> False) True listMap :: (a -> b) -> List a -> List b listMap f = uncons (\x xs -> Cons (f x) (listMap f xs)) Nil newtype ListS a = ListS { unconsS :: forall r. (a -> ListS a -> r) -> r -> r } nilS :: ListS a nilS = ListS (\co ni -> ni) consS :: a -> ListS a -> ListS a consS x xs = ListS (\co ni -> co x xs) unconsS' :: (a -> ListS a -> r) -> r -> ListS a -> r unconsS' co ni (ListS f) = f co ni instance Functor ListS where fmap f = unconsS' (\x xs -> consS (f x) (fmap f xs)) nilS -- Church Encoding newtype ListC a = ListC { foldC :: forall r. (a -> r -> r) -> r -> r } foldC' :: (a -> r -> r) -> r -> ListC a -> r foldC' co ni (ListC f) = f co ni instance Functor ListC where fmap f = foldC' (\x xs -> consC (f x) xs) nilC consC = undefined nilC = undefined -- GADTs and continuation passing style data Some :: * -> * where SomeInt :: Int -> Some Int SomeChar :: Char -> Some Char Anything :: a -> Some a unSome :: Some a -> a unSome (SomeInt x) = x + 3 unSome (SomeChar c) = toLower c unSome (Anything x) = x newtype SomeC a = SomeC { runSomeC :: forall r. ((a ~ Int) => Int -> r) -> ((a ~ Char) => Char -> r) -> (a -> r) -> r } -- dependent types idk :: forall (a :: *). a -> a idk x = x