我正在尝试为F#
中的添加实现以下递归定义m + 0:= m
m +(n + 1):=(m + n)+ 1
我似乎无法使语法正确,我最接近的是
let rec plus x y =
match y with
| 0 -> x;
| succ(y) -> succ( plus(x y) );
其中succ n = n + 1.它会对succ的模式匹配引发错误。
答案 0 :(得分:3)
我不确定succ
在您的示例中的含义,但它不是标准F#库中定义的模式。仅使用基本功能,您将需要使用匹配任何数字的模式,然后减去一个(并在正文中添加一个):
let rec plus x y =
match y with
| 0 -> x
| y -> 1 + (plus x (y - 1))
在F#中(与Prolog中的不同),您无法在模式中使用自己的函数。但是,您可以定义活动模式,指定如何将输入分解为各种情况。以下采用整数并返回Zero
(对于零)或Succ y
对于值y + 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)
答案 1 :(得分:2)
正如托马斯所说,你不能在没有声明的情况下使用这样的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
会隐藏第一个{{1}}。但我认为这样做会使代码混乱。
答案 2 :(得分:1)
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
答案 3 :(得分:0)
let rec plus x y =
match y with
| 0 -> x
| _ -> plus (x+1) (y-1)