Skip to content

Instantly share code, notes, and snippets.

@louispan
Last active May 7, 2018 06:06
Show Gist options
  • Save louispan/f340a7f77623aeda3fd8927f00adcf66 to your computer and use it in GitHub Desktop.
Save louispan/f340a7f77623aeda3fd8927f00adcf66 to your computer and use it in GitHub Desktop.
Haskell - Advanced Overlap
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
-- https://wiki.haskell.org/GHC/AdvancedOverlap
-- when using closed type family, data kinds, and proxy
module Main where
import Data.Proxy
class Print' flag a where
print' :: Proxy flag -> a -> IO ()
class Print a where
print :: a -> IO ()
-- Is there a way to avoid this explicitness?
type family ShowPred a where
ShowPred Int = 'True
ShowPred Bool = 'True
ShowPred [a] = ShowPred a
ShowPred a = 'False
instance Show a => Print' 'True a where
print' _ x = putStrLn (show x)
instance Print' 'False a where
print' _ _ = putStrLn "No show method"
instance (Print' (ShowPred a) a) => Print a where
print a = print' (flag a) a
where
flag :: a -> Proxy (ShowPred a)
flag _ = Proxy