2011-07-30 5 views
4

は、以下の例を考えてみますHaskell - typeclassを追加しますか?

data Dot = Dot Double Double 
data Vector = Vector Double Double 

まず、私はVector追加のため+演算子をオーバーロードしたいと思います。私は平等(==)演算子をオーバーロードしたい場合、私はそれが好きで記述します。

instance Eq Vector where ...blahblahblah 

しかし、ほかの操作を持つタイプのようなVector振る舞いをするAdd型クラスがある場合、私は見つけることができません。私はハスケルのタイプメタルの完全なリストを見つけることさえできません。私はいくつかのチュートリアルからしか知りません。そのようなリストは存在しますか?

また、オペレータにVectorDotの演算子をオーバーロードすることはできますか(これは論理的ではありませんか?)。

+1

なぜ点とベクトルを区別する必要がありますか?他の人が触れたように、Num型のクラスには(+)がありますが、両方の引数が同じ型でなければならないので、ドットとベクトルで(+)を実装することはできません。2つの型が互換性があると考えることができる場合は、1つの型しか持たず、その型をNumのインスタンスにすることができます。 – Boris

+1

おそらく 'Num 'を探しているかもしれませんが、' Monoid'型のクラスがあなたにとって興味深いかもしれません。他のリソースの中で、[LYAH#monoids](http://learnyouahaskell.com/functors-applicative-functors-and-monoids#monoids) –

答えて

7

Preludeの演算子+は、Typeclass Numで定義されています。しかし、名前が示唆するように、これは追加だけでなく、他の多くの数値演算(特に数値演算子と同様に他の算術演算子も使用できる)を定義しているので、これはユースケースには当てはまりません。

Preludeの+演算子を非表示にしたい場合を除いて、あなたの型に+をオーバーロードする方法はありません(Integer、Doubleなどの独自のAddableインスタンスを作成しなければならない場合は、数字に+を使用します)。

+3

を参照してください。Numを実装して、 (+)は定義されていません。実際には、Haskellのプログラマは時々typeclassesを実装し、未定義のメソッドをいくつか残します。 –

5

instance Num Vectorをベクトル加算(および意味をなす演算子)のためにオーバーロードするには+と書くことができます。

instance Num Vector where 
    (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2) 
    -- and so on 

しかし、全て+タイプNum a => a -> a -> a、すなわち、オペランドの両方と結果であることに注意同じ型でなければなりません。つまり、DotVectorを加えたものはDotにできません。

PreludeからNumを非表示にして、独自の+を指定することはできますが、これは混乱の原因となり、通常の算術と組み合わせて使用​​することを難しくします。

私はあなたが短いものを好む場合は、例えば、

(Dot x y) `offsetBy` (Vector dx dy) = Dot (x + dx) (y + dy) 

またはいくつかの変種の記号を使用するため、ベクトル点の加算のために独自の演算子を定義示唆しています。

+0

'(+)'、または 'Num'のすべてを隠し、あなた自身の代わりに使うことの間違い*は何もありません。問題は、本当に醜いハッキング以外のものとしてそうすることです、あなたは基本的にPreludeの数値クラスのほとんどを完全に置き換えることを強いられてしまいます。 –

13

型クラス(もしあれば)関数が属するかについての情報を発見する簡単な方法は、GHCiのを使用することです:私は時々種類のプレリュードからのもののように見える自分のオペレータを定義する人々を参照してください

Prelude> :i (+) 
class (Eq a, Show a) => Num a where 
    (+) :: a -> a -> a 
    ... 
     -- Defined in GHC.Num 
infixl 6 + 
4

++でも、2つのリストを一緒に「追加」する考えを伝えるものが必要だったので、おそらくそのシンボルを使用しますが、リストがNumのインスタンスであるとは意味がありません。したがって、<+>または|+|などを使用できます。

関連する問題