[英]Recursive addition in F# using
I'm trying to implement the following recursive definition for addition in F# 我正在尝试为F#实现以下递归定义
m + 0 := m m + 0:= m
m + (n + 1) := (m + n) + 1 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. succ n = n +1。在succ的模式匹配上引发错误。
I'm not sure what succ
means in your example, but it is not a pattern defined in the standard F# library. 我不确定
succ
在您的示例中是什么意思,但这不是标准F#库中定义的模式。 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 eg in Prolog), you can't use your own functions inside patterns. 在F#中(不同于Prolog),您不能在模式内部使用自己的函数。 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
: 以下代码取一个整数,并为值
y + 1
返回Zero
(对于零)或Succ y
:
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)
As Tomas said, you can't use succ
like this without declaring it. 正如Tomas所说,您不能在不声明的情况下使用
succ
。 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: 然后在
plus
函数中使用它:
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. 如果将
y
放在我有y1
,则代码将起作用,因为第二个y
将隐藏第一个。 But I think doing so makes the code confusing. 但是我认为这样做会使代码混乱。
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
let rec plus x y =
match y with
| 0 -> x
| _ -> plus (x+1) (y-1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.