簡體   English   中英

將值從Frege傳遞到Java並返回

[英]Passing Values From Frege to Java and Back

假設我有一個啞啞Frege函數,它構造了一對Num

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

但是,嘗試從Java調用此函數,除了期望的Lazy<α>Lazy<β>之外,還需要PreludeBase.CNum<α>PreludeBase.CNum<β> Lazy<β> 同樣,對於Show類型,

showSomething :: (Show α) => α -> String
showSomething = show
-- alternatively -- showSomething x = show x

除預期參數外,還需要PreludeBase.CShow<α>

在Java中來回傳遞約束的Frege對象的正確方法是什么?

很好的問題,因為這在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是找出這一點的最佳方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM