2013-10-25 3 views
-2

Я делаю одно из своих домашних заданий, чтобы преобразовать целое число меньше 5000 в римскую цифру.Haskell Mod и Int to Numeral

Вот мой код intToRoman

mrepeat :: Integer -> String -> String 
mrepeat numRepeat strRepeat 
| numRepeat == 0 = "" 
| otherwise = strRepeat ++ mrepeat (numRepeat - 1) strRepeat 

romanLetter :: [String] 
romanValue :: [Int] 
romanLetter = ["I", "V", "X", "L", "C", "D", "M"] 
romanValue = [1, 5, 10, 50, 100, 500, 1000] 
convertIter :: Int -> Integer -> String 
convertIter count number 
| count == -1 = "" 
| mod count 2 == 0 && q == 4 = (romanLetter !! count) ++ (romanLetter !! (count + 1)) ++ (convertIter (count - 1) r) 
| mod count 2 == 1 && (mod (number + (romanValue !! (count - 1))) romanValue !! count) == 2 = (romanLetter !! (count - 1)) ++ (romanLetter !! (count + 1)) ++ (convertIter (count - 1) r) 
| otherwise = (mrepeat q (romanLetter !! (count - 1))) ++ (convertIter !! (count - 1) r) 
where (q, r) = divMod number romanValue !! count 

intToRoman :: Integer -> String 
intToRoman number = convertIter 6 number 

Извините за исходное сообщение, что я не ясно показать сообщение об ошибке. А вот сообщение об ошибке:

test.hs:14:25: 
    No instance for (Integral [a0]) 
     arising from a use of `mod' 
    Possible fix: add an instance declaration for (Integral [a0]) 
    In the first argument of `(!!)', namely 
     `mod (number + (romanValue !! (count - 1))) romanValue' 
    In the first argument of `(==)', namely 
     `(mod (number + (romanValue !! (count - 1))) romanValue !! count)' 
    In the second argument of `(&&)', namely 
     `(mod (number + (romanValue !! (count - 1))) romanValue !! count) 
    == 
     2' 

test.hs:14:30: 
    Couldn't match expected type `[a0]' with actual type `Integer' 
    In the first argument of `(+)', namely `number' 
    In the first argument of `mod', namely 
     `(number + (romanValue !! (count - 1)))' 
    In the first argument of `(!!)', namely 
     `mod (number + (romanValue !! (count - 1))) romanValue' 

test.hs:14:37: 
    No instance for (Num [a0]) 
     arising from a use of `+' 
    Possible fix: add an instance declaration for (Num [a0]) 
    In the first argument of `mod', namely 
     `(number + (romanValue !! (count - 1)))' 
    In the first argument of `(!!)', namely 
     `mod (number + (romanValue !! (count - 1))) romanValue' 
    In the first argument of `(==)', namely 
     `(mod (number + (romanValue !! (count - 1))) romanValue !! count)' 

test.hs:16:17: 
    Couldn't match expected type `[(t0, t1)]' 
       with actual type `(a0, a0)' 
    In the return type of a call of `divMod' 
    In the first argument of `(!!)', namely `divMod number romanValue' 
    In the expression: divMod number romanValue !! count 
Failed, modules loaded: none. 
+0

то, что ошибка? можете ли вы опубликовать его и удалить номер строки из кода для чтения? – jev

+0

«Некоторая ошибка» - какая ошибка? – MrKWatkins

+2

SO не является местом, где люди могут ** угадать ** о вашей ошибке. Мы могли бы также ответить «Некоторые изменения должны быть внесены в ваш код. Готово». – Ingo

ответ

1

Это не совсем ответ на ваш вопрос. Это ответ на ваше задание. Таким образом, его нельзя считать правильным, но я думал, что кто-то захочет его увидеть.

intToRoman :: Integer -> String 
intToRoman n 
    | n >= 1000 = 'M'  : intToRoman (n - 1000) 
    | n >= 900 = 'C' : 'M' : intToRoman (n - 900) 
    | n >= 500 = 'D'  : intToRoman (n - 500) 
    | n >= 400 = 'C' : 'D' : intToRoman (n - 400) 
    | n >= 100 = 'C'  : intToRoman (n - 100) 
    | n >= 90 = 'X' : 'C' : intToRoman (n - 90) 
    | n >= 50 = 'L'  : intToRoman (n - 50) 
    | n >= 40 = 'X' : 'L' : intToRoman (n - 40) 
    | n >= 10 = 'X'  : intToRoman (n - 10) 
    | n >= 9 = 'I' : 'X' : intToRoman (n - 9) 
    | n >= 5 = 'V'  : intToRoman (n - 5) 
    | n >= 4 = 'I' : 'V' : intToRoman (n - 4) 
    | n >= 1 = 'I'  : intToRoman (n - 1) 
    | otherwise = [] 

Вдохновленный this implementation