【问题标题】:Passing Values From Frege to Java and Back将值从 Frege 传递到 Java 并返回
【发布时间】:2016-05-17 15:39:40
【问题描述】:

假设我有一个哑弗雷格函数,它构造了一对Nums。

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 的正确方法是什么?

【问题讨论】:

    标签: java frege


    【解决方案1】:

    好问题,因为这在 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
    

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

    的 Show 实例
    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 实例,它是Num 的子类。不幸的是,只有编译器知道某些类型实际存在哪些实例,哪些实例是隐式的,即由子类的实例提供。同样,REPL 是找出这一点的最佳方法。

    【讨论】:

      猜你喜欢
      • 2016-04-11
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      • 2021-01-24
      • 2012-02-18
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多