例如,在一个分支中,我想查看一个数字可以被 1000 整除的次数,然后将少于该数量的起始数递归传递到函数中。这是我写的:
if num // 1000 > 0 then
repeat (num // 1000) (String.fromChar 'M')
convertToRom (num % 1000)
但是,我在测试时在 REPL 中收到以下错误:
> getRomNums 3500
-- TYPE MISMATCH ----------------------------------------- ..RomanNumerals.elm
Function `repeat` is expecting 2 arguments, but was given 4.
34| repeat (num // 1000) (String.fromChar 'M')
35|> convertToRom (num % 1000)
Maybe you forgot some parentheses? Or a comma?
如何为单个 if 分支编写多行代码?
不相关的旁注:格式系统使双斜杠成为注释,但在 Elm 中,双斜杠是整数除法。不知道如何解决这个问题。
在Elm(以及其他函数式语言,如Haskell(中,你不会像在命令式语言中那样在迭代步骤中编写代码。每个函数都必须返回一个值,逻辑的每个分支都必须返回一个值。关于如何在 Elm 中"做多件事",没有单一的答案,但使用 Elm 的类型系统、元组和递归,你会发现缺乏命令式并不能真正阻止你做任何事情。这只是从以命令式风格编写代码的范式转变。
为了您编写罗马数字转换函数的目的,我认为直接的答案在于对结果使用显式递归和字符串连接:
convertToRom : Int -> String
convertToRom num =
if num // 1000 > 0 then
String.repeat (num // 1000) (String.fromChar 'M') ++ convertToRom (num % 1000)
else if ...
else
""
随着函数式编程工具集的增长,您会发现自己越来越少地显式使用递归,并且依赖于更高级别的抽象,如折叠和映射。