3

haskellの機能依存関係 wiki

これらの定義を考えると:

data Vector = Vector Int Int deriving (Eq, Show)
data Matrix = Matrix Vector Vector deriving (Eq, Show)
instance Num Vector where
  Vector a1 b1 + Vector a2 b2 = Vector (a1+a2) (b1+b2)
  Vector a1 b1 - Vector a2 b2 = Vector (a1-a2) (b1-b2)
  {- ... and so on ... -}

instance Num Matrix where
  Matrix a1 b1 + Matrix a2 b2 = Matrix (a1+a2) (b1+b2)
  Matrix a1 b1 - Matrix a2 b2 = Matrix (a1-a2) (b1-b2)
  {- ... and so on ... -}
class Mult a b c where
  (*) :: a -> b -> c

instance Mult Matrix Matrix Matrix where
  {- ... -}

instance Mult Matrix Vector Vector where
  {- ... -}

次のようなあいまいなタイプがある理由がわかりません。

m1, m2, m3 :: Matrix
(m1 * m2) * m3              -- type error; type of (m1*m2) is ambiguous

明らかに、m1m2Matrixの場合、可能なリターンのタイプはMatrixのみです。つまり、を適用しinstance Mult Matrix Matrix Matrixます。

4

2 に答える 2

6

問題は型クラス宣言にあります

class Mult a b c where
  (*) :: a -> b -> c

2 つの引数に適用する(*)と、結果の型を決定する方法がありません。次の 2 つのインスタンスがあるとします。

instance Mult Int Int Int where ...
instance Mult Int Int Integer where ...

次に、 の型だけでなく、2 * 4の型にもなる可能性があります。IntInteger

これで、インスタンスが 1 つしかないと主張できるので、コンパイラは文句を言うべきではありません。しかし、Haskell 型クラスはオープンワールドに存在します。インスタンスはいつでも追加できます。また、他の場所でコードを壊してはなりません。したがって、インスタンスが 1 つしかない場合でも、別のライブラリの誰かが別のインスタンスを追加できます。そして、2 つのライブラリがあり、それぞれが機能しますが、一緒に失敗します。これは明らかに不正確です。Real World Haskellのオープンワールドでの生活を参照してください。

したがって、一般に、型クラス内の関数の戻り値の型は、その引数から派生可能でなければなりません。これはまさに機能依存関係の目的です。宣言すれば

class Mult a b c | a b -> c where

コンパイラは、 の戻り値の型が何であるかを常に知ることができます(*)

于 2013-02-04T18:08:10.120 に答える
1

あなたが他のすべての可能性を忘れたので、例えば

 instance Mult Matrix Matrix Vector where
 instance Mult Vector Matrix Vector where
 instance Mult Float Matrix Float where
 instance Mult Matrix Matrix Float where  -- etc.

 a :: Vector
 a = (m1 >< m2:: Vector) >< m3

 b :: Float
 b = (m1 >< m2:: Float) >< m3

クラス定義への機能依存性の追加:

instance Mult a b c | a b -> c

それは

instance Mult Matrix Matrix Matrix

2つの行列の問題を決定します

instance Mult Matrix Matrix Vector
instance Mult Matrix Matrix Float

Matrix'aとMatrix。'の積を表示する別の方法を提供するため、除外されます。したがって、直感的に感じている状況は、機能依存性で得られる状況です。

関数従属性が次のように定式化された場合:

 instance Mult a b c | b -> a c

これにより、指定した2つのインスタンスも許可されます。

 instance Mult Matrix Matrix Matrix where
 instance Mult Matrix Vector Vector where

しかし、私が想像した他のすべてMatrixb位置を除外します(あいまいな例では、行列の積の結果としてではなく、としてm3説明されていたため、必要に応じて)。Matrix

于 2013-02-04T18:05:53.810 に答える