| 1 | {-# LANGUAGE EmptyDataDecls, |
|---|
| 2 | MultiParamTypeClasses, |
|---|
| 3 | FunctionalDependencies, |
|---|
| 4 | OverlappingInstances, |
|---|
| 5 | FlexibleInstances, |
|---|
| 6 | UndecidableInstances #-} |
|---|
| 7 | module Main where |
|---|
| 8 | |
|---|
| 9 | import Prelude hiding (print) |
|---|
| 10 | |
|---|
| 11 | class Print a where |
|---|
| 12 | print :: a -> IO () |
|---|
| 13 | |
|---|
| 14 | {- the following does not work: |
|---|
| 15 | instance Show a => Print a where |
|---|
| 16 | print x = putStrLn (show x) |
|---|
| 17 | instance Print a where |
|---|
| 18 | print x = putStrLn "No show method" |
|---|
| 19 | |
|---|
| 20 | error: |
|---|
| 21 | Duplicate instance declarations: |
|---|
| 22 | instance (Show a) => Print a -- Defined at /tmp/wiki.hs:7:0 |
|---|
| 23 | instance Print a -- Defined at /tmp/wiki.hs:9:0 |
|---|
| 24 | -} |
|---|
| 25 | |
|---|
| 26 | class Print' flag a where |
|---|
| 27 | print' :: flag -> a -> IO () |
|---|
| 28 | |
|---|
| 29 | instance (ShowPred a flag, Print' flag a) => Print a where |
|---|
| 30 | print = print' (undefined::flag) |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | -- overlapping instances are used only for ShowPred |
|---|
| 34 | class ShowPred a flag | a->flag where {} |
|---|
| 35 | |
|---|
| 36 | -- Used only if the other |
|---|
| 37 | -- instances don't apply |
|---|
| 38 | instance TypeCast flag HFalse => ShowPred a flag |
|---|
| 39 | |
|---|
| 40 | instance ShowPred Int HTrue -- These instances should be |
|---|
| 41 | instance ShowPred Bool HTrue -- the same as Show's |
|---|
| 42 | instance ShowPred a flag => ShowPred [a] flag |
|---|
| 43 | -- ...etc... |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | data HTrue -- Just two |
|---|
| 47 | data HFalse -- distinct types |
|---|
| 48 | |
|---|
| 49 | instance Show a => Print' HTrue a where |
|---|
| 50 | print' _ x = putStrLn (show x) |
|---|
| 51 | instance Print' HFalse a where |
|---|
| 52 | print' _ x = putStrLn "No show method" |
|---|
| 53 | |
|---|
| 54 | test1 = print [True,False] -- [True,False] |
|---|
| 55 | test2 = print id -- No show method |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | -- see http://okmij.org/ftp/Haskell/typecast.html |
|---|
| 61 | class TypeCast a b | a -> b, b->a where typeCast :: a -> b |
|---|
| 62 | class TypeCast' t a b | t a -> b, t b -> a where typeCast' :: t->a->b |
|---|
| 63 | class TypeCast'' t a b | t a -> b, t b -> a where typeCast'' :: t->a->b |
|---|
| 64 | instance TypeCast' () a b => TypeCast a b where typeCast x = typeCast' () x |
|---|
| 65 | instance TypeCast'' t a b => TypeCast' t a b where typeCast' = typeCast'' |
|---|
| 66 | instance TypeCast'' () a a where typeCast'' _ x = x |
|---|
| 67 | |
|---|