Created
February 15, 2018 16:57
-
-
Save neongreen/63dbf00821bca1d00456bd346bff0210 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# OPTIONS -Wall #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE ViewPatterns #-} | |
{-# LANGUAGE PatternSynonyms #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE OverloadedLabels #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE MagicHash #-} | |
import GHC.TypeLits | |
import GHC.OverloadedLabels | |
import GHC.Prim | |
---------------------------------------------------------------------------- | |
-- main | |
---------------------------------------------------------------------------- | |
main :: IO () | |
main = say #hi >> say #bye | |
say :: OneOf ["hi", "bye"] -> IO () | |
say (#hi -> True) = putStrLn "Hello world!" | |
say (#bye -> True) = putStrLn "Goodbye!" | |
---------------------------------------------------------------------------- | |
-- Implementation | |
---------------------------------------------------------------------------- | |
instance {-# OVERLAPPING #-} | |
IsLabel name (OneOf (name : xs)) where | |
fromLabel _ = OneOf 0 | |
-- TODO: can be optimized to O(1) by doing all the work at the typelevel | |
instance {-# OVERLAPPABLE #-} | |
IsLabel name (OneOf xs) => IsLabel name (OneOf (y : xs)) where | |
fromLabel _ = let OneOf n = fromLabel @name @(OneOf xs) proxy# | |
in OneOf (n+1) | |
instance IsLabel name (OneOf xs) => IsLabel name (OneOf xs -> Bool) where | |
fromLabel _ = (== fromLabel @name @(OneOf xs) proxy#) | |
data OneOf (names :: [Symbol]) = OneOf Int | |
deriving Eq | |
{- | |
data Atom (name :: Symbol) = Atom | |
instance IsLabel name (Atom name) where | |
fromLabel _ = Atom |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment