将值从 Frege 传递到 Java 并返回
Passing Values From Frege to Java and Back
假设我有一个构造一对 Num
s 的愚蠢 Frege 函数。
newPair :: (Num α, Num β) => α -> β -> (α, β)
newPair = (,)
-- alternatively -- newPair x y = (x, y)
尝试从 Java 调用此函数,但是,除了预期的 Lazy<α>
和 Lazy<β>
之外,还需要 PreludeBase.CNum<α>
和 PreludeBase.CNum<β>
.同样 Show
类型,其中
showSomething :: (Show α) => α -> String
showSomething = show
-- alternatively -- showSomething x = show x
除了预期的参数之外还需要一个 PreludeBase.CShow<α>
。
将受约束的 Frege 对象传入和传出 Java 的正确方法是什么?
问得好,因为 wiki 中还没有对此进行解释。
在所有此类情况下,我建议使用
:java
REPL 中的命令。例如:
frege> newPair 1 2.3
frege> :java
然后您将得到一个 window,其中包含所有活动定义中与此调用相对应的一个。一个简单的文本搜索可以帮助找到调用 newPair
的地方。大多数情况下,这应该有助于解决此类问题。
在您的情况下,相关部分如下所示:
Console.<Integer, Double>numPair(
PreludeBase.INum_Int.it,
PreludeBase.IReal_Double.it,
Thunk.<Integer>lazy(1),
Thunk.<Double>lazy(2.3))
这里简要概述了类型 classes 和实例的命名方式以及如何获取它们。
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 ...
部分结果 class
a.b.C.IXable_MyType /* implements CXable<TMyType> */
如果您的实例定义本身没有约束,将有一个您可以使用的单例实例。
a.b.C.IXable_MyType.it
否则,您需要通过将所有约束作为参数传递给构造函数来构造一个新实例。例如,
的 Show 实例
Maybe Int
看起来像这样:
new IShow_Maybe(IShow_Int.it)
因为实例头列出了 Maybe 元素类型的约束:
instance Show a => Show (Maybe a)
请注意,您需要完全了解实际类型,不能创建泛型类型 class 实例。这在 Frege 本身从来都不是问题,因为所有需要的实例都从调用者传递给多态函数。然而,就目前而言,我们在本机函数中没有限制。
如果您需要这样的东西,在大多数情况下,您只需将要调用的函数作为参数传递即可实现该功能。
例如,这行不通:
pure native myMethod :: Show a => a -> ...
但这应该:
pure native myMethod :: (a -> String) -> a -> ....
myMethod show (Just 47)
上面的示例 java 代码还表明它并不总是像描述的那样简单。例如,碰巧 Double
类型没有单独的 Num
实例,而只有 Real
的一个实例,它是 [=25= 的子 class ].不幸的是,只有编译器知道某些类型实际存在哪些实例,哪些实例是隐式的,即由子 class 的实例提供。同样,REPL 是找出这一点的最佳方式。
假设我有一个构造一对 Num
s 的愚蠢 Frege 函数。
newPair :: (Num α, Num β) => α -> β -> (α, β)
newPair = (,)
-- alternatively -- newPair x y = (x, y)
尝试从 Java 调用此函数,但是,除了预期的 Lazy<α>
和 Lazy<β>
之外,还需要 PreludeBase.CNum<α>
和 PreludeBase.CNum<β>
.同样 Show
类型,其中
showSomething :: (Show α) => α -> String
showSomething = show
-- alternatively -- showSomething x = show x
除了预期的参数之外还需要一个 PreludeBase.CShow<α>
。
将受约束的 Frege 对象传入和传出 Java 的正确方法是什么?
问得好,因为 wiki 中还没有对此进行解释。
在所有此类情况下,我建议使用
:java
REPL 中的命令。例如:
frege> newPair 1 2.3
frege> :java
然后您将得到一个 window,其中包含所有活动定义中与此调用相对应的一个。一个简单的文本搜索可以帮助找到调用 newPair
的地方。大多数情况下,这应该有助于解决此类问题。
在您的情况下,相关部分如下所示:
Console.<Integer, Double>numPair(
PreludeBase.INum_Int.it,
PreludeBase.IReal_Double.it,
Thunk.<Integer>lazy(1),
Thunk.<Double>lazy(2.3))
这里简要概述了类型 classes 和实例的命名方式以及如何获取它们。
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 ...
部分结果 class
a.b.C.IXable_MyType /* implements CXable<TMyType> */
如果您的实例定义本身没有约束,将有一个您可以使用的单例实例。
a.b.C.IXable_MyType.it
否则,您需要通过将所有约束作为参数传递给构造函数来构造一个新实例。例如,
的 Show 实例Maybe Int
看起来像这样:
new IShow_Maybe(IShow_Int.it)
因为实例头列出了 Maybe 元素类型的约束:
instance Show a => Show (Maybe a)
请注意,您需要完全了解实际类型,不能创建泛型类型 class 实例。这在 Frege 本身从来都不是问题,因为所有需要的实例都从调用者传递给多态函数。然而,就目前而言,我们在本机函数中没有限制。
如果您需要这样的东西,在大多数情况下,您只需将要调用的函数作为参数传递即可实现该功能。
例如,这行不通:
pure native myMethod :: Show a => a -> ...
但这应该:
pure native myMethod :: (a -> String) -> a -> ....
myMethod show (Just 47)
上面的示例 java 代码还表明它并不总是像描述的那样简单。例如,碰巧 Double
类型没有单独的 Num
实例,而只有 Real
的一个实例,它是 [=25= 的子 class ].不幸的是,只有编译器知道某些类型实际存在哪些实例,哪些实例是隐式的,即由子 class 的实例提供。同样,REPL 是找出这一点的最佳方式。