module Music.Pitch.Relative.Quality (
Augmentable(..),
Quality(..),
HasQuality(..),
isPerfect,
isMajor,
isMinor,
isAugmented,
isDiminished,
diffToQuality,
qualityToDiff,
invertQuality,
replicate',
) where
class Augmentable a where
augment :: a -> a
diminish :: a -> a
data Quality
= Major
| Minor
| Perfect
| Augmented Integer
| Diminished Integer
deriving (Eq, Ord)
instance Show Quality where
show Major = "_M"
show Minor = "m"
show Perfect = "_P"
show (Augmented n) = "_" ++ replicate' n 'A'
show (Diminished n) = replicate' n 'd'
instance HasQuality Quality where
quality = id
class HasQuality a where
quality :: a -> Quality
invertQuality :: Quality -> Quality
invertQuality = go
where
go Major = Minor
go Minor = Major
go Perfect = Perfect
go (Augmented n) = Diminished n
go (Diminished n) = Augmented n
isPerfect :: HasQuality a => a -> Bool
isPerfect a = case quality a of { Perfect -> True ; _ -> False }
isMajor :: HasQuality a => a -> Bool
isMajor a = case quality a of { Major -> True ; _ -> False }
isMinor :: HasQuality a => a -> Bool
isMinor a = case quality a of { Minor -> True ; _ -> False }
isAugmented :: HasQuality a => a -> Bool
isAugmented a = case quality a of { Augmented _ -> True ; _ -> False }
isDiminished :: HasQuality a => a -> Bool
isDiminished a = case quality a of { Diminished _ -> True ; _ -> False }
diffToQuality :: Bool -> Int -> Quality
diffToQuality = go
where
go True 0 = Perfect
go True n = if n > 0 then Augmented (fromIntegral n) else Diminished (fromIntegral $ negate n)
go False 0 = Major
go False (1) = Minor
go False n = if n > 0 then Augmented (fromIntegral n) else Diminished (fromIntegral $ negate $ n + 1)
qualityToDiff :: Bool -> Quality -> Int
qualityToDiff perfect = go
where
go (Diminished n) = fromIntegral $ negate $ if perfect then n else n + 1
go Minor = fromIntegral $ 1
go Perfect = fromIntegral $ 0
go Major = fromIntegral $ 0
go (Augmented n) = fromIntegral $ n
replicate' n = replicate (fromIntegral n)