Skip to content

Instantly share code, notes, and snippets.

@rybla
Last active November 23, 2021 15:34
Show Gist options
  • Save rybla/8bcb406bf8f28fd7bb50d9792a08d91c to your computer and use it in GitHub Desktop.
Save rybla/8bcb406bf8f28fd7bb50d9792a08d91c to your computer and use it in GitHub Desktop.
{-# LANGUAGE GADTs, KindSignatures, DataKinds, RankNTypes, TypeFamilies, TypeFamilyDependencies, AllowAmbiguousTypes, ScopedTypeVariables #-}
module OverloadSingletonI where
import Prelude hiding (negate)
data OverloadMode = NegateInt | NegateBool
data SOverloadMode :: OverloadMode -> * -> * where
SNegateInt :: SOverloadMode NegateInt (Int -> Int)
SNegateBool :: SOverloadMode NegateBool (Bool -> Bool)
type family OverloadType (mode :: OverloadMode) = r | r -> mode where
OverloadType NegateInt = Int -> Int
OverloadType NegateBool = Bool -> Bool
class SOverloadModeI (mode :: OverloadMode) where
sOverloadMode :: SOverloadMode mode (OverloadType mode)
instance SOverloadModeI NegateInt where
sOverloadMode = SNegateInt
instance SOverloadModeI NegateBool where
sOverloadMode = SNegateBool
negate :: forall (mode :: OverloadMode). SOverloadModeI mode => OverloadType mode
negate = negate' sOverloadMode
negate' :: forall (mode :: OverloadMode). SOverloadMode mode (OverloadType mode) -> OverloadType mode
negate' SNegateInt = \x -> (- x)
negate' SNegateBool = \b -> not b
negate_1 :: Int
negate_1 = negate (1 :: Int)
negate_True :: Bool
negate_True = negate True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment