从Java调用Frege不会';不匹配参数的数目

从Java调用Frege不会';不匹配参数的数目,java,compilation,frege,Java,Compilation,Frege,我有如下Frege代码(主要注意getDatabase的类型签名) 我在后者中加了null,这只是为了表明我传入的内容并不重要。我不知道为什么我必须应用函数三次(我不能立即强制求值)。我有没有办法删除应用程序,或者对为什么需要它们进行合理化? (注意:使用.result()对这种情况没有帮助。)我确信其他人可以提供更好的答案,但在强制计算延迟时必须传递额外参数的原因是IO和STMutable类型 我在这里遇到了同样的问题: 可能值得考虑一种实用方法“deeplyForced”(?),它可以使Ja

我有如下Frege代码(主要注意getDatabase的类型签名)

我在后者中加了null,这只是为了表明我传入的内容并不重要。我不知道为什么我必须应用函数三次(我不能立即强制求值)。我有没有办法删除应用程序,或者对为什么需要它们进行合理化?
(注意:使用.result()对这种情况没有帮助。)

我确信其他人可以提供更好的答案,但在强制计算延迟时必须传递额外参数的原因是IO和STMutable类型

我在这里遇到了同样的问题:


可能值得考虑一种实用方法“deeplyForced”(?),它可以使Java开发人员免受这些细节的影响。

原因是在这个实现中,ST操作被表示为“函数对象”,其中实现伴随函数的方法忽略它的参数

回顾ST的定义可能有助于理解:

abstract data ST s a = ST (s -> a) where ...
首先要注意的是,
数据
实际上是用Haskell编写的
newtype
。所以
ST
只是一个类型重命名,也就是说,ST操作实际上是一个函数

但是,
abstract
确保您无法查看
ST
数据构造函数,因此无法直接从Frege代码运行函数

这解释了为什么在Java中,在将参数应用于返回
ST
操作的函数之后,需要将额外的参数应用于结果,正如我们所看到的,结果只是另一个函数

那么,为什么要在代码中执行两次呢?因为
IO
是(从我的头顶):

STMutable

type STMutable s x = ST s (Mutable s x)
因此问题在于
getDatabase
函数,它返回一个
IO
操作,执行时返回一个ST操作,执行时返回一个可变数组列表

这可能不是你想要的。我猜你在
getDatabase
中的最后一行有点纠结,应该是:

list <- ArrayList.new ()
foldM (\xs\x -> ArrayList.add xs x >> return xs) list processedData 
或者只是

IOMutable ArrayList
此外还有一点:您不需要重新引入
split
,它已经存在了。您可以编写将分号分隔的输入行分开的行:

[ (a,b) | line <- lines fileContent, [a,b] <- ´;´.splitted line ]

[(a,b)| line这个实用方法确实存在,它的名称是
IO.performUnsafe
(我应该把它添加到我的答案中)。但这里的要点是OP嵌套了两个级别的ST(我猜是无意的)。太好了,谢谢你的回复。我不确定IO/ST/Mutable/IOMutable/MutableIO等的所有定义是如何嵌套和连接的。如果有相关资源,我将不胜感激。另外,ST.performUnsafe位于frege端——是否有一种安全、健壮的方法从Java端强制执行?@Crazycolorz5,所有这些都在-要查看如何将某些表达式转换为Java,请在REPL中输入表达式并使用:Java命令。例如:加载并导入Frege模块,然后键入
ST.performUnsafe(getDatabase“foo”)
nd使用类型检查器确认后,键入
:java
表达式对应的代码显示在末尾附近。
type STMutable s x = ST s (Mutable s x)
list <- ArrayList.new ()
foldM (\xs\x -> ArrayList.add xs x >> return xs) list processedData 
IO (Mutable RealWorld ArraList)
IOMutable ArrayList
[ (a,b) | line <- lines fileContent, [a,b] <- ´;´.splitted line ]