18

これで機能する演算子を定義したい(それを呼び出す+-+):

if a,b are Char    => a +-+ b = [a][b]
if a,b are Integer => a +-+ b = a+b

私は試しました:

class Summable a where
    (+-+)       :: a -> a -> b

instance Summable Integer where
    a +-+ b     = a + b

instance Summable Char where
    a +-+ b     = [a] ++ [b]

しかし、私はエラーが発生します:

Couldn't match type `b' with `Integer'....
Couldn't match type `b' with `[Char]' ....

これを行うことは可能ですか?どのように?

4

1 に答える 1

25

問題は、型変数bが修正されているにもかかわらず、インスタンスから判別できないことです。(そのような自由変数を持つには、関数が任意の型を持つ何かを返す必要がありますundefined。)

+-+タイプを教えてくださいa -> a -> a。もしそうなら、そうしてください。(しかし、これは不可能のようです。)

それ以外の場合は、関数の依存関係を使用して、インスタンスが結果の型を指定するか、型ファミリを使用して、インスタンス化の属性の 1 つが結果の型になるようにすることができます。

機能的な依存関係の場合、コードは次のようになります。

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class Summable a result | a -> result where
  (+-+) :: a -> a -> result

instance Summable Char String where
  a +-+ b = [a] ++ [b]

instance Summable Integer Integer where
  a +-+ b = a + b

型ファミリの場合、次のようになります。

{-# LANGUAGE TypeFamilies #-}

class Summable a where
  type Result a
  (+-+) :: a -> a -> Result a

instance Summable Char where
  type Result Char = String
  a +-+ b = [a] ++ [b]

instance Summable Integer where
  type Result Integer = Integer
  a +-+ b = a + b

(私が犯したさまざまなエラーを修正してくれた Vitus と Vladimir Matveev に感謝します! :) )

于 2012-08-22T15:41:00.593 に答える