open number string math digit x y z k = [[x],[x,x],[x,x,x],[x,y],[y],[y,x],[y,x,x],[y,x,x,x],[x,z]] : (toInt k - 1) toRoman 0 = "" toRoman x | x < 0 = fail "Negative roman numeral" | x >= 1000 = 'M' :: toRoman (x - 1000) | x >= 100 = let (q,r) = x `divrem` 100 in digit 'C' 'D' 'M' q ++ toRoman r | x >= 10 = let (q,r) = x `divrem` 10 in digit 'X' 'L' 'C' q ++ toRoman r | else = digit 'I' 'V' 'X' x map (join "" << toRoman) [1999,25,944]