F# 中的递归加法使用

发布于 2024-12-11 01:45:17 字数 347 浏览 3 评论 0原文

我正在尝试在 F#

m + 0 := m

m + (n + 1) := (m + n) + 1

中实现以下加法的递归定义我似乎无法获得正确的语法,最接近的我've come is

let rec plus x y =                        
 match y with                     
 | 0 -> x;                        
 | succ(y) -> succ( plus(x y) );

其中 succ n = n + 1。它会在 succ 的模式匹配上引发错误。

I'm trying to implement the following recursive definition for addition in F#

m + 0 := m

m + (n + 1) := (m + n) + 1

I can't seem to get the syntax correct, The closest I've come is

let rec plus x y =                        
 match y with                     
 | 0 -> x;                        
 | succ(y) -> succ( plus(x y) );

Where succ n = n + 1. It throws an error on pattern matching for succ.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请远离我 2024-12-18 01:45:17

我不确定 succ 在您的示例中意味着什么,但它不是标准 F# 库中定义的模式。仅使用基本功能,您需要使用匹配任何数字的模式,然后减一(并在主体中加一):

let rec plus x y =                         
 match y with                      
 | 0 -> x                     
 | y -> 1 + (plus x (y - 1))

在 F# 中(与 Prolog 等不同),您不能在模式中使用自己的函数。但是,您可以定义活动模式来指定如何将输入分解为各种情况。下面的代码接受一个整数,并返回 Zero(零)或 Succ yy + 1

let (|Zero|Succ|) n = 
  if n < 0 then failwith "Unexpected!"
  if n = 0 then Zero else Succ(n - 1)

然后您可以编写以下代码 :更接近您的原始版本:

let rec plus x y =
  match y with
  | Zero -> x
  | Succ y -> 1 + (plus x y)

I'm not sure what succ means in your example, but it is not a pattern defined in the standard F# library. Using just the basic functionality, you'll need to use a pattern that matches any number and then subtract one (and add one in the body):

let rec plus x y =                         
 match y with                      
 | 0 -> x                     
 | y -> 1 + (plus x (y - 1))

In F# (unlike e.g. in Prolog), you can't use your own functions inside patterns. However, you can define active patterns that specify how to decompose input into various cases. The following takes an integer and returns either Zero (for zero) or Succ y for value y + 1:

let (|Zero|Succ|) n = 
  if n < 0 then failwith "Unexpected!"
  if n = 0 then Zero else Succ(n - 1)

Then you can write code that is closer to your original version:

let rec plus x y =
  match y with
  | Zero -> x
  | Succ y -> 1 + (plus x y)
绅刃 2024-12-18 01:45:17

正如 Tomas 所说,如果不声明它,就不能像这样使用 succ 。您可以做的是创建一个代表数字的可区分联合:

type Number = 
| Zero
| Succ of Number

然后在 plus 函数中使用它:

let rec plus x y =
 match y with
 | Zero -> x
 | Succ(y1) -> Succ (plus x y1)

或者您可以将其声明为 + 运算符:

let rec (+) x y =
 match y with
 | Zero -> x
 | Succ(y1) -> Succ (x + y1)

如果您将 y 保留在我的 y1 位置,该代码可以工作,因为第二个 y 会隐藏第一个。但我认为这样做会使代码变得混乱。

As Tomas said, you can't use succ like this without declaring it. What you can do is to create a discriminated union that represents a number:

type Number = 
| Zero
| Succ of Number

And then use that in the plus function:

let rec plus x y =
 match y with
 | Zero -> x
 | Succ(y1) -> Succ (plus x y1)

Or you could declare it as the + operator:

let rec (+) x y =
 match y with
 | Zero -> x
 | Succ(y1) -> Succ (x + y1)

If you kept y where I have y1, the code would work, because the second y would hide the first one. But I think doing so makes the code confusing.

九局 2024-12-18 01:45:17
type N = Zero | Succ of N

let rec NtoInt n =
  match n with
  | Zero -> 0
  | Succ x -> 1 + NtoInt x

let rec plus x y =
  match x with
  | Zero -> y
  | Succ n -> Succ (plus n y)

演示:

> plus (Succ (Succ Zero)) Zero |> NtoInt ;;
val it : int = 2
> plus (Succ (Succ Zero)) (Succ Zero) |> NtoInt ;;
val it : int = 3
type N = Zero | Succ of N

let rec NtoInt n =
  match n with
  | Zero -> 0
  | Succ x -> 1 + NtoInt x

let rec plus x y =
  match x with
  | Zero -> y
  | Succ n -> Succ (plus n y)

DEMO:

> plus (Succ (Succ Zero)) Zero |> NtoInt ;;
val it : int = 2
> plus (Succ (Succ Zero)) (Succ Zero) |> NtoInt ;;
val it : int = 3
慈悲佛祖 2024-12-18 01:45:17
let rec plus x y =
    match y with
    | 0 -> x
    | _ -> plus (x+1) (y-1)
let rec plus x y =
    match y with
    | 0 -> x
    | _ -> plus (x+1) (y-1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文