[英]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.