2012-12-04 20 views
6

まあ、私は型の周りを頭で囲んでいるので、幾何ベクトル操作のための型クラスを定義しようとしています。私はそれをコンポーネントワイズ+,-,*,/;のために働かせることができましたが、私はドットプロダクトに苦労しています。結果はタイプFractional a、ないDoubleであるためHaskell Vector Typeclass:[a] - > [a] - > aの関数

class GeomVector a where 
    (>+) :: a -> a -> a 
    (>-) :: a -> a -> a 
    (>*) :: a -> a -> a 
    (>/) :: a -> a -> a 

    (>.) :: a -> a -> Double 

data Vector a = Vec [a] 
       deriving Show 

instance (Fractional a) => GeomVector (Vector a) where 
    (>+) (Vec u) (Vec v) = Vec $ zipWith (+) u v 
    (>-) (Vec u) (Vec v) = Vec $ zipWith (-) u v 
    (>*) (Vec u) (Vec v) = Vec $ zipWith (*) u v 
    (>/) (Vec u) (Vec v) = Vec $ zipWith (/) u v 

    (>.) (Vec u) (Vec v) = sum $ u >* v 

明らかに(>。)のための私のインスタンス定義は機能しません。

しかし、この動作をクラスの宣言から取得する方法はわかりません。

class GeomVector [a] where 
    (>.) :: [a] -> [a] -> a 

しかし[a]がタイプとないタイプの変数であるため、これは無効です:私がやりようをいただきたい何

です。

私はこのことについて少し説明したいと思っていますが、私は正直なところ理解できません。うまくいけば、コードは、私が苦労していることをもう少し明白にするでしょう。

+1

スカラーの型を表す別の型変数、つまり 'class GeomVector a ... where(...。):: a - > a - > s'が必要だと思います。 – ErikR

+2

あなたが望むものは[関連タイプの同義語]です(http://www.haskell.org/haskellwiki/GHC/Type_families#An_associated_type_synonym_example) – Lambdageek

+0

結果の型が(>。)であるだけでなく、クラス宣言にも瑕疵があります。 '' 'u''と' 'v''の内積を生成しようとしていますが、これはあなたのクラスのインスタンスではなく のリストです。 –

答えて

5

ここで仕事ができる一つの選択肢だ:

class GeomVector v where 
    (>+) :: Num a=> v a -> v a -> v a 
    (>-) :: Num a=> v a -> v a -> v a 
    (>*) :: Num a=> v a -> v a -> v a 
    (>/) :: Fractional a=> v a -> v a -> v a 
    (>.) :: Num a=> v a -> v a -> a 

data Vector a = Vec { vecList :: [a] } 
       deriving Show 

instance GeomVector Vector where 
    (>+) (Vec u) (Vec v) = Vec $ zipWith (+) u v 
    (>-) (Vec u) (Vec v) = Vec $ zipWith (-) u v 
    (>*) (Vec u) (Vec v) = Vec $ zipWith (*) u v 
    (>/) (Vec u) (Vec v) = Vec $ zipWith (/) u v 

    (>.) u v = sum $ vecList (u >* v) 

だからGeomVectorのすべてのインスタンスがMonadクラスのような種類* -> *を持つことになります。そして、メソッドの型は、あなたがそこのどこかで分割するだけなので、Fractional型に不必要に制限されません。

クラスをできるだけ小さくすることも考えてみましょう(>.はクラス外の多相関数にしてください)。本当に必要なものは、まず型クラスです。しかし、それはあなたがデザインしているものに依存しています。私はそれについてあなたがよく知っていると推測したくありません!

+0

'> .'をクラスの外に移動することはおそらくできません。なぜなら、それは合計を行うには' GeomVector'の各インスタンスの内部構造について知る必要があるからです。 – huon

+1

この問題は 'toList'を追加することで解決できます。 –

+0

よろしくお願いいたします。だから、もし意味があれば、クラス 'class(Foldable v)=> GeomVector v'を作るオプションがあります。 – jberryman

関連する問題