3

我正在将这个包移植到 Java,并且在试图解决两种语言之间的懒惰/急切的不和谐时遇到了困难。我不认为它会像现在这样严重,因为实现完全取决于函数类型,但我想我错了。我如何保持足够的懒惰来让它工作?或者,我如何最小限度地重写它,使其对 Java 足够渴望?

编码

现在直接在 pastebin 上可用,谢谢你告诉我。

InfiniteListException.java

TransformFunc.java

变换CSFunc.java

调频.java

FMList.java

问题

我几乎在每个“函数式”方法上都会遇到堆栈溢出(呵呵),并且force()必须几乎不断地调用它们,以防止它们即使在没有进行功能编码时也是如此。

4

3 回答 3

3

你会讨厌我的回答,因为将代码从函数式语言转换为命令式语言真的很痛苦,即使它看起来并不那么明显。

基本上你可以做两件事:

  1. 重写以删除递归。这并不总是可能的,也不容易。有时,有一种算法可以做到这一点(我唯一能想到的就是当函数是尾递归时,但可能还有更多)。其他时候,您必须自己完成工作并编写与原始函数相同的自定义函数,但不使用递归。

  2. 您可以构建自己的类似调用堆栈的系统来使用,而不是使用该语言正在使用的调用堆栈。这允许您对函数式语言进行优化,但命令式语言不这样做,它允许您为每个函数拥有一个堆栈,这确实减少了堆栈用完的机会,它还允许您拥有一个堆栈你喜欢的尺寸。

当然,您可以根据需要将这两种技术结合起来,因为基本上您需要为脚本中使用的每个函数提供一个解决方案。

正如我所说,这不是好消息。这是一个非常糟糕的消息,因为这意味着如果您想将此(或任何其他)函数库移植到命令式世界,还有很多工作要做。

于 2012-02-05T11:25:46.003 回答
1

我对 FoldMap 不熟悉,但是一些功能 Java 的List函数(也是ArraysStreams)是在内部使用常量堆栈空间实现的,例如查看foldLeftforeach,也许它们可以提供帮助..

于 2012-03-04T19:02:50.997 回答
1

一种非常规的方法是使用Frege编译稍微修改的 Haskell 源代码。

所需的修改通常仅限于出口清单(弗雷格没有)和进口。

于 2012-11-09T14:53:29.927 回答