:それはない明らかだ場合パターン:私は、次のGADTを定義した
data Vector v where
Zero :: Num a => Vector a
Scalar :: Num a => a -> Vector a
Vector :: Num a => [a] -> Vector [a]
TVector :: Num a => [a] -> Vector [a]
、私はシンプルなベクトル空間を実装しようとしています。すべてのベクトル空間にベクトルを追加する必要があるので、Vector
とinstance
をNum
にして実装します。ベクトル空間では、異なる長さのベクトルを追加するのは意味がありません。これは私が強制したいものです。私はそれがガードを使用することだろう行うことを考えた一つの方法:
instance Num (Vector v) where
(Vector a) + (Vector b) | length a == length b =
Vector $ zipWith (+) a b
| otherwise =
error "Only add vectors with the same length."
あり、このアプローチには、実際には何の問題もありませんが、パターンマッチングでこれを行う方法がなければならないような気がします。それを行うには、おそらく一つの方法は、次のようなものになり、新しいデータ型VectorLength
、定義するために次のようになります。そして、
data Length l where
AnyLength :: Nat a => Length a
FixedLength :: Nat a -> Length a
を、長さ成分は、Vector
データ型にこのようなものを追加することができます。
data Vector (Length l) v where
Zero :: Num a => Vector AnyLength a
-- ...
Vector :: Num a => [a] -> Vector (length [a]) [a]
これは正しい構文ではないことがわかりましたが、これは私がやっている一般的な考えです。最後に、あなたは追加の
instance Num (Vector v) where
(Vector l a) + (Vector l b) = Vector $ zipWith (+) a b
はそのようなことが可能であり、またはこの目的のためにパターンマッチングを使用する他の方法があることを定義することができますか?
Hmm。これは少し残念ですが、Haskellにこのような機能が実装されていないと、私は何もできないと思います。ありがとう。 – Max
私は本当に固定ベクトルを見てみることをお勧めしますが、これらの方法のどれも素晴らしいものではありません。 –
GHC 7.8では、この構文に非常に近いものが有効であることに注意してください。この宣言はGHC 7.6でも使えるが、算術演算は役に立たない。 – Carl