【问题标题】: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 

【问题讨论】:

  • 我会先写下这些函数的类型,然后看看它的去向。

标签: functional-programming sml


【解决方案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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      相关资源
      最近更新 更多