【发布时间】:2017-10-11 16:39:43
【问题描述】:
我最近开始学习 Haskell,目前正在尝试编写基本的 Haskell 函数。
我编写了一个名为intToRoman 的函数,它应该将整数转换为罗马数字。它将整数列表中的数字 (1400 ->[1,4,0,0]) 相除,然后根据列表的帐户长度将每个数字转换为罗马数字,以确定是一千还是一百。
但是,它不会停止并检查零。例如,数字 1400 将返回:
MCD** Exception: Map.!: given key is not an element in the map
CallStack (from HasCallStack)
这是代码本身:
mapInttoRoman:: M.Map Int String
mapInttoRoman = M.fromList
[(1,"I"),(4,"IV"),(5,"V"),(9,"IX"),(10,"X"),(40,"XL")
,(50,"L"),(100,"C"),(400,"CD"),(900,"CM"),(500,"D"),(1000,"M")]
listOfInt :: Int -> [Int]
listOfInt 0 = [ ]
listOfInt c = listOfInt(c`div`10) ++ [c`mod`10]
duplicate :: String -> Int -> String
duplicate string n = concat $ replicate n string
intToRoman :: Int -> String
intToRoman 0 = ""
intToRoman c = createInt x (len-1)
where x = listOfInt c
len = length x
createInt y xz = findRoman (head y) xz ++ createInt(drop 1 y)(xz-1)
where findRoman b l
| l < 1 = mapInttoRoman M.! b
| b == 0 = " "
| l == 3 = duplicate (mapInttoRoman M.! (10^l)) b
| b == 1 = mapInttoRoman M.! (10^l)
| otherwise = mapInttoRoman M.! (b*10^l)
【问题讨论】:
-
您的
| b == 0 = " "案例无法捕捉到这一点,因为首先检查了| l < 1 = ..案例。你可以切换他们的顺序。 (然后它会失败,因为您尝试获取空列表的头部,因此您必须为createInt [] _ = ""添加基本情况) -
我知道您可能是 Haskell 的新手,但请考虑阅读style guide。这不是好的代码。
-
@AJFarmar 我认为当您学习一门具有许多新概念的新语言并为自己的教育编写程序时,担心这根本不是正确的事情。样式指南对于需要维护的程序很重要。
标签: haskell