使用F#中的递归加法

时间:2011-10-19 10:52:44

标签: syntax f#

我正在尝试为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的模式匹配引发错误。

4 个答案:

答案 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)