相互递归高阶
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 -> bool
,twoElse
的类型为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】:目前oneElse
和twoElse
的定义不是相互递归的。为了能够建立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;
【讨论】:
以上是关于相互递归高阶的主要内容,如果未能解决你的问题,请参考以下文章