Any pointers on how to make the closed type family example from the Haskell Wiki compile?
GHC/AdvancedOverlap (Solution 3)
Here is the version I tried:
{-# LANGUAGE
DataKinds,
FlexibleInstances,
MultiParamTypeClasses,
TypeFamilies,
UndecidableInstances #-}
data HTrue
data HFalse
type family ShowPred a where
ShowPred Int = HTrue
ShowPred Bool = HTrue
ShowPred [a] = ShowPred a
ShowPred a = HFalse
class Print a where
print :: a -> IO ()
instance (ShowPred a ~ flag, Print' flag a) => Print a where
print = print' (undefined :: flag)
class Print' flag a where
print' :: flag -> a -> IO ()
instance Show a => Print' HTrue a where
print' _ x = putStrLn (show x)
instance Print' flag a where
print' _ _ = putStrLn "No show method"
However, this still gives me:
Overlapping instances for Print' flag0 a.
(GHC 8.0.1 is the version I am using.)
Edit: Defining the second instance as Print' HFalse a
results in:
Could not deduce (Print' flag0 a) arising from a use of print' from the context: (ShowPred a ~ flag, Print' flag a).
Edit: Here is the example with all the corrections. All credit goes to @dfeuer.
{-# LANGUAGE
DataKinds,
FlexibleInstances,
MultiParamTypeClasses,
ScopedTypeVariables,
TypeFamilies,
UndecidableInstances #-}
import Prelude hiding (print)
import Data.Proxy
data HTrue
data HFalse
type family ShowPred a where
ShowPred Int = HTrue
ShowPred Bool = HTrue
ShowPred [a] = ShowPred a
ShowPred a = HFalse
class Print a where
print :: a -> IO ()
instance (ShowPred a ~ flag, Print' flag a) => Print a where
print = print' (Proxy :: Proxy flag)
class Print' flag a where
print' :: Proxy flag -> a -> IO ()
instance Show a => Print' HTrue a where
print' _ x = putStrLn (show x)
instance Print' HFalse a where
print' _ _ = putStrLn "No show method"
instance Print' HFalse a
for your second instance – Benjamin Hodgson♦