相互递归高阶

Posted

技术标签:

【中文标题】相互递归高阶【英文标题】:Mutual recursion higher order 【发布时间】:2021-11-19 07:22:38 【问题描述】:

有没有办法使用相互递归来创建使用现有状态的状态机。



fun oneElse f xs =
    case xs of
    1::xs' => f xs'
      | [] => true
      | _ => false;
         
fun twoElse xs =
    case xs of
    2::xs' => oneElse twoElse xs'
      | []  => false
      | _ => false

val oneTwo = oneElse twoElse [1,2,1,2];

这是我目前所拥有的,但我想要的是高阶函数采用这些通用(下一个不知道)状态。


fun oneElse f xs  = ...
         
fun twoElse f xs = ...


val oneTwo = oneElse (twoElse (oneElse headache) ) xs 

【问题讨论】:

我会先写下这些函数的类型,然后看看它的去向。 【参考方案1】:

由于循环性,您不能直接执行此操作; oneElse 的类型为type of twoElse -> int list -> booltwoElse 的类型为type of oneElse -> int list -> bool,所以oneElse 的类型为(type of oneElse -> int list -> bool) -> int list -> bool,无限扩展。

但是,您可以使用标准解决方案来解决这个问题 - 添加一个间接级别。

datatype Wrap = Wrap of (Wrap -> int list -> bool)

fun oneElse (Wrap f) (1::xs) = f (Wrap oneElse) xs
  | oneElse _ [] = true
  | oneElse _ _ = false


fun twoElse (Wrap f) (2::xs) = f (Wrap twoElse) xs
  | twoElse _ _ = false;

现在这两个函数的类型都是 Wrap -> int list -> bool,这可以解决。 你只需要在传递函数时包装它们,然后在应用它们之前解包。

测试:

- oneElse (Wrap twoElse) [1,2,1,2];
val it = true : bool

- oneElse (Wrap twoElse) [1,2,1];
val it = false : bool

【讨论】:

【参考方案2】:

目前oneElsetwoElse 的定义不是相互递归的。为了能够建立mutuality,我们必须让oneElse使用twoElse,反之亦然。

不确定它是否会达到预期目的......一种方法是按照以下方式定义两个函数,展示mutual recursion

fun oneElse xs =
    case xs of
        1::xs' => twoElse xs'
      | [] => true
      | _ => false
and twoElse xs =
    case xs of
        2::xs' => oneElse xs'
      | []  => false
      | _ => false;

【讨论】:

以上是关于相互递归高阶的主要内容,如果未能解决你的问题,请参考以下文章

python入门16 递归函数 高阶函数

递归函数和高阶函数

高阶函数-递归

8.5高阶函数递归函数和内置函数

递归函数与高阶函数

Javascript中具有递归的高阶函数