考虑:
{-# OPTIONS -fglasgow-exts #-}
data Second = Second
data Minute = Minute
data Hour = Hour
-- Look Ma', a phantom type!
data Time a = Time Int
instance Show (Time Second) where
show (Time t) = show t ++ "sec"
instance Show (Time Minute) where
show (Time t) = show t ++ "min"
instance Show (Time Hour) where
show (Time t) = show t ++ "hrs"
sec :: Int -> Time Second
sec t = Time t
minute :: Int -> Time Minute
minute t = Time t
hour :: Int -> Time Hour
hour t = Time t
class TimeAdder a b c | a b -> c where
add :: Time a -> Time b -> Time c
instance TimeAdder Second Second Second where
add (Time s1) (Time s2) = sec (s1 + s2)
instance TimeAdder Second Minute Second where
add (Time s) (Time m) = sec (s + 60*m)
instance TimeAdder Second Hour Second where
add (Time s) (Time h) = sec (s + 3600*h)
instance TimeAdder Minute Second Second where
add (Time m) (Time s) = sec (60*m + s)
instance TimeAdder Minute Minute Minute where
add (Time m1) (Time m2) = minute (m1 + m2)
instance TimeAdder Minute Hour Minute where
add (Time m) (Time h) = minute (m + 60*h)
instance TimeAdder Hour Second Second where
add (Time h) (Time s) = sec (3600*h + s)
instance TimeAdder Hour Minute Minute where
add (Time h) (Time m) = minute (60*h + m)
instance TimeAdder Hour Hour Hour where
add (Time h1) (Time h2) = hour (h1 + h2)
add (minute 5) (hour 2)
--125min
虽然我很高兴像这样疯狂的东西能奏效,但我想知道如何TimeAdder
避免实例的二次爆炸。