【问题标题】:Using folding procedures in sml在 sml 中使用折叠程序
【发布时间】:2013-10-23 19:33:17
【问题描述】:
fun Dbt (nil,_) =  nil
  | Dbt (x::xs,y::ys) = (x::y)::(Dbt(xs,ys))
  | Dbt (x::xs,nil) = [x]::(Dbt(xs,nil));

有没有办法通过使用高阶和或在 sml 中的内置函数来非递归地定义这个函数?

【问题讨论】:

  • 我实际上想用这个函数来帮助我完成另一个高阶函数的定义,它不应该使用由案例或递归定义的函数。换句话说,我想让它成为一个迭代器我的“foldr”功能——作业的一部分,是的

标签: ocaml sml smlnj


【解决方案1】:

由于您不是消费列表而是生产它们,因此您将无法使用通常的列表遍历运算符(map、filter、fold... )。

然而,有一个常见且易于理解的列表生成组合器,即

val unfold : ('a -> ('a * 'b) option) -> 'a -> 'b list

很遗憾,此运算符在基本 SML 库中不可用,因此您可能必须自己定义。

fun Dbt (xs, ys) =
  let fun Step (nil, _) = NONE
      |   Step (x::xs, y::ys) = SOME (x::y,(xs,ys))
      |   Step (x::xs, nil) = SOME ([x], (xs,nil))
  in unfold Step (xs, ys)

【讨论】:

  • 我正在努力解决这个问题,但我对 let 表达式的结构有点困惑。Step 到底是什么?它看起来像我的 Dbt,你能解释一下吗?
  • Step 确实拥有Dbt 的所有有用内容,但它不是递归的。这个想法是它执行“一步”计算,返回列表的下一个元素应该是什么(根据其输入,您可以认为在列表生成期间转换的状态)。您应该尝试根据我给出的类型签名编写(递归)组合器unfold,通过将它们组合在一起,您将能够更好地理解Step
  • 您可能不想声明三个不同的函数,称为Step,而是声明一个具有三种情况的函数(使用| Step (x::xs...)。 (我会解决这个问题,但显然 StackOverflow 不会轻易让我这样做。)
  • 确实,抱歉,我搞砸了我生锈的 SML 语法。
猜你喜欢
  • 2012-03-26
  • 2012-11-10
  • 2017-01-30
  • 2019-04-01
  • 2013-12-25
  • 2016-05-10
  • 2021-09-13
  • 2013-03-10
  • 2016-06-08
相关资源
最近更新 更多