【问题标题】:Recursion in F#, expected type int but got type "int list -> int"F# 中的递归,预期类型为 int,但类型为“int list -> int”
【发布时间】:2017-10-24 15:45:45
【问题描述】:

我是 F# 的新手,想通过递归实现列表的最小公用多重函数,例如lcm(a,b,c) = lcm(a, lcm(b,c)),其中两个元素的 lcm 由 gcd 计算得出。

我有以下代码。我尝试将 lcm 函数的输入与一个包含两个元素的列表匹配,否则就是一个通用列表,我将其拆分为第一个元素和其余部分。 “lcm (tail)”部分给出了编译器错误。它说它应该具有“int”类型,但具有“int list -> int”类型。看起来它说“lcm tail”这个表达式本身就是一个函数,我不明白。为什么不是int?

let rec gcd a b =
    if b = 0
        then abs a
    else gcd b (a % b)

let lcmSimple a b = a*b/(gcd a b)

let rec lcm list = function
    | [a;b] -> lcmSimple a b
    | head::tail -> lcmSimple (head) (lcm (tail))

最好的问候。

【问题讨论】:

  • 也许,你的意思只是let rec lcm = function
  • 但仍然注意警告 - 您不会处理所有可能的情况。
  • @FoggyFinder 你是对的,如果我删除“列表”它会起作用,但通常你会在你的函数中包含一个参数。我意识到我从不使用“列表”,也许它是一个匹配的东西。另外,我已经包括了空的情况。
  • let rec lcm list = function | ...let rec lcm list x = match x with | ... 的简写,因此您的函数需要 2 个参数,而不是 1 个。
  • 所以,必须有人写答案。 @HowDoICSharply 你想做吗?

标签: recursion f# tail-recursion


【解决方案1】:

将函数定义为 let f = function | ... 时,函数的参数是隐式的,因为它被解释为 let f x = match x with | ...

因此let rec lcm list = function |... 是两个变量的函数,它们是list 和隐式变量。这就是为什么编译器声称lcm tail 是一个函数的原因——只传递了一个变量,而它预期有两个。更好的代码版本是

let rec gcd a b =
    if b = 0
        then abs a
    else gcd b (a % b)

let lcmSimple a b = a*b/(gcd a b)

let rec lcm = function
    | [a;b] -> lcmSimple a b
    | head::tail -> lcmSimple (head) (lcm (tail))
    | [] -> 1

包含最后一个案例以完成模式。

【讨论】:

    猜你喜欢
    • 2021-05-28
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多