Skip to content

Instantly share code, notes, and snippets.

@jhrcek
Created October 7, 2020 16:22
Show Gist options
  • Save jhrcek/ba6909c95b0d1ade1b1cbdc6912a7335 to your computer and use it in GitHub Desktop.
Save jhrcek/ba6909c95b0d1ade1b1cbdc6912a7335 to your computer and use it in GitHub Desktop.
Playing with dependent types in Haskell
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
module Main where
import Data.Char (toUpper)
import Data.Constraint (Dict (..))
import Data.Proxy (Proxy (..))
import System.Environment (getArgs)
import System.IO (interact)
import Text.Read (readMaybe)
data SBool (b :: Bool) where
STrue :: SBool 'True
SFalse :: SBool 'False
fromSBool :: SBool b -> Bool
fromSBool STrue = True
fromSBool SFalse = False
data SomeSBool where
SomeSBool :: SBool b -> SomeSBool
withSomeSBool :: SomeSBool -> (forall (b :: Bool). SBool b -> r) -> r
withSomeSBool (SomeSBool s) f = f s
toSBool :: Bool -> SomeSBool
toSBool True = SomeSBool STrue
toSBool False = SomeSBool SFalse
class Echo (scream :: Bool) where
echoStdin :: Proxy scream -> IO ()
instance Echo 'True where
echoStdin _ = interact (fmap toUpper)
instance Echo 'False where
echoStdin _ = interact id
main :: IO ()
main = do
args <- getArgs
let scream = case args of
["--scream"] -> True
_ -> False
withSomeSBool (toSBool scream) $
\(sb :: SBool b) ->
case dict @Echo sb of
Dict -> echoStdin (Proxy @b)
dict :: (c 'True, c 'False) => SBool b -> Dict (c b)
dict STrue = Dict
dict SFalse = Dict
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment