module Music.Parts.Division (
Division,
division,
getDivision,
divisions,
showDivision,
showDivisionR,
) where
import Control.Applicative
import Control.Lens (toListOf)
import Data.Aeson (ToJSON (..), FromJSON(..))
import qualified Data.Aeson
import Data.Default
import Data.Functor.Adjunction (unzipR)
import Data.Semigroup
import Data.Semigroup.Option.Instances
import Data.Traversable (traverse)
import Data.Typeable
import Text.Numeral.Roman (toRoman)
newtype Division = Division { getDivision :: (Int, Int) }
deriving (Eq, Ord)
instance Show Division where
show (Division (n,m)) = "division " ++ show n ++ show m
instance Default Division where
def = Division (0,1)
instance ToJSON Division where
toJSON (getDivision -> (x,y)) = Data.Aeson.object [("num-parts",toJSON y),("part-div",toJSON (x + 1))]
instance FromJSON Division where
parseJSON (Data.Aeson.Object v) = do
x <- v Data.Aeson..: "part-div"
y <- v Data.Aeson..: "num-parts"
return $ division (x 1) y
parseJSON _ = empty
showDivisionR :: Division -> String
showDivisionR = toRoman . succ . fst . getDivision
showDivision :: Division -> String
showDivision = show . succ . fst . getDivision
division :: Int -> Int -> Division
division n m
| n < 0 || m <= 0 = error "Invalid division"
| n < m = Division (n, m)
| otherwise = error "Invalid division"
divisions :: Int -> [Division]
divisions n = [Division (x,n) | x <- [0..n1]]