2016-05-17 10 views
1

Numのペアを構成するダムのFrege関数があるとします。 Javaからこの関数を呼び出そうとFregeからJavaへの値の受け渡し

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

、しかし、PreludeBase.CNum<α>PreludeBase.CNum<β>は期待Lazy<α>Lazy<β>に加えて、要求されています。同様に

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

が予想されるパラメータに加えてPreludeBase.CShow<α>を必要とするShow種類、と。

制限付きFregeオブジェクトをJavaとの間でやりとりする適切な方法は何ですか?

答えて

2

良い質問ですが、これはまだwikiで説明されていないためです。

はこのようなすべてのケースのように、私はREPLで

:java 

コマンドを使用することをお勧めします。例:

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)) 

型クラスとインスタンスが命名され、どのようにあなたがそれらを得ることができる方法についての短いoverwiewです。

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

これは

x.y.Z.CXable 

そして、この完全修飾名を使用してJavaインタフェースになり:いくつかのクラスで

結果

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

あなたのインスタンスの場合定義に制約がないあなたが使うことができるシングルトンのインスタンスがあります。

a.b.C.IXable_MyType.it 

そうしないと、あなたは、コンストラクタの引数としてすべての制約を渡すことによって、新しいインスタンスを作成する必要があります。インスタンスヘッドはたぶん、要素タイプの制約を示していますので、

new IShow_Maybe(IShow_Int.it) 

:たとえば、

Maybe Int 

を表示インスタンスは、次のようになり

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インスタンスがなく、NumのサブクラスであるRealのインスタンスが1つだけ存在します。残念ながら、コンパイラだけは、ある種のインスタンスに実際にどのインスタンスが存在し、どのインスタンスが暗黙的に存在するのか、つまりサブクラスのインスタンスによって提供されているのかを知っています。繰り返しますが、REPLがこれを見つけ出す最良の方法です。

関連する問題