将值从Frege传递到Java并返回

时间:2016-05-17 15:39:40

标签: java frege

假设我有一个愚蠢的弗雷格函数来构造一对Num

newPair :: (Num α, Num β) => α -> β -> (α, β)
newPair = (,)
-- alternatively -- newPair x y = (x, y)

但是,尝试从Java调用此函数时,除了预期的PreludeBase.CNum<α>PreludeBase.CNum<β>之外,还需要Lazy<α>Lazy<β>。与Show类型相同,其中

showSomething :: (Show α) => α -> String
showSomething = show
-- alternatively -- showSomething x = show x
除了预期的参数外,

还需要PreludeBase.CShow<α>

将受约束的Frege对象传递给Java和从Java传递的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

很好的问题,因为wiki尚未对此进行解释。

在所有这种情况下,我建议使用

:java
REPL中的

命令。例如:

frege> newPair 1 2.3
frege> :java

然后,您将获得一个窗口,其中包含与此调用相对应的所有活动定义。简单的文本搜索可以帮助找到调用newPair的位置。这应该有助于在大多数时间解决这些问题。

在您的情况下,相关部分将如下所示:

Console.<Integer, Double>numPair(
   PreludeBase.INum_Int.it, 
   PreludeBase.IReal_Double.it, 
   Thunk.<Integer>lazy(1), 
   Thunk.<Double>lazy(2.3))

以下是关于如何命名类型类和实例以及如何获取它们的简短概述。

module x.y.Z where
    class Xable where ...

这导致Java接口具有完全限定名称

x.y.Z.CXable

而且:

module a.b.C where
    import x.y.Z
    data MyType ... = ....
    instance Xable MyType where ...

导致某些课程

a.b.C.IXable_MyType  /* implements CXable<TMyType> */

如果您的实例定义本身没有约束,则可以使用单个实例。

a.b.C.IXable_MyType.it

否则,您需要通过将所有约束作为参数传递给构造函数来构造新实例。例如,显示

的实例
Maybe Int

看起来像这样:

new IShow_Maybe(IShow_Int.it)

因为实例头列出了Maybe元素类型的约束:

instance Show a => Show (Maybe a)

请注意,您需要完全了解实际类型,不能创建泛型类实例。这在Frege本身从来都不是问题,因为所有需要的实例都从调用者传递给多态函数。但是,就目前而言,我们对本机功能没有限制。

如果你需要这样的东西,你可以通过传递你想要作为参数调用的函数来实现大多数情况下的功能。

例如,这不起作用:

pure native myMethod :: Show a => a -> ...

但这应该:

pure native myMethod :: (a -> String) -> a -> ....
myMethod show (Just 47)

上面的示例java代码也表明它并不总是像描述的​​那样容易。例如,恰好Double类型没有单独的Num实例,而只有Real的一个实例,Numinterp1的子类。不幸的是,只有编译器知道某些类型实际存在哪些实例,哪些是隐式的,即由子类的实例提供。同样,REPL是找到它的最好方法。