3

Haskell は初めてで、インスタンスを持つクラスを作成しようとしていました。

私は次のコードを持っており、それを言おうとしています: 1) ブランチは最初の位置に任意の型を保持できます。2) 線形のものを取り、数値を返すクラス Linear を作成します。 Branch が最初に保持するのは、Num クラスの一部です。

data Branch a = Branch a Integer deriving (Show, Eq)

class Linear l where
    length :: (Num a) => l -> a

instance (Num a) => Linear (Branch a) where
    length (Branch len _) = len

次のエラーが表示されます: Could not deduce (a ~ a1) from the context (Num a) bound by the instance definition at.....

私が言おうとしていることを Haskell で表現する方法を知っている人はいますか?

4

1 に答える 1

8

クラス定義ではlength、ユーザーが要求する任意のNumタイプを返すことができる必要があります。したがって、ユーザーが整数を必要とする場合、lengthメソッドはユーザーに整数を与える必要があります。そして、代わりにIntまたはDoubleが必要な場合は、長さもそれを与える必要があります。

ただし、インスタンス宣言で指定する長さ関数は要件を満たしていません。たとえば、でlengthを呼び出すとBranch Integer、lengthは。を返しますInteger。ユーザーが要求しても、Intまたはを返しません。Double

コードを機能させる1つの方法は、マルチパラメーター型クラスを使用して、2つのパラメーターでLinearを定義することです。ここで、2番目の型は数値型lengthが返す必要があります。次に、のインスタンスを作成できますLinear (Branch a) a。これをより使いやすくするために、FunctionalDependencies拡張機能を使用することもできます。2番目のタイプパラメータの代わりに、タイプファミリ拡張機能を使用して同様の効果を実現することもできます。

もう1つの方法は、インスタンス宣言を変更して、Integral a代わりにrequireに変更し、戻り値としてNum a使用することです。fromIntegral lenこれにより、ブランチに格納されている整数型が、ユーザーが要求した数値型に変換されます。もちろん、非整数の数値で分岐する場合は、Linearこの方法のインスタンスにはならないことに注意してください。

于 2012-07-19T03:31:44.917 に答える