1

私はこのコードを持っています:

data SafeValue a = SafeValue a a a deriving Eq

class Safe a where
  check::a->Bool
  (+++)::a->a->a

instance (Num a, Eq a) => Safe (SafeValue a) where
  check (SafeValue x y z) | x == y = True
                          | x == z = True
                          | y == z = True
                          | otherwise = False
  (SafeValue a b c)+++(SafeValue x y z) = let new_val = SafeValue (a+x) (b+y) (c+z)
                                          in if check new_val then new_val
                                                              else error "Error"

class Safe次のような関数に追加したいと思います。

make_new 3 --> SafeValue 3 3 3

ティッピーは次のようになるはずなので、追加する方法がわかりません。

make_new::b->a

しかし、istance宣言の中で、ghciそれが何でbあるかは定かではないと主張しています。

誰か助けてもらえますか?

4

1 に答える 1

5

中心的な問題は、すべてのタイプで の値を生成するためにmake_new機能することを約束していることです。ただし、これはどのように機能するかを考えると意味がありません。何らかの type が与えられると、out が得られます。したがって、あなたが本当に望むのは、 forが何らかの型の値を取り、 の値を与えることです。より一般的には、結果は、インスタンスを作成している実際の型であり、任意の型にすることができる何らかの型にする必要があります。baSafeValue aaSafeValue amake_newaSafeValue as asa

あなたがする必要があるのは、クラスが「より高次の」型の値を受け入れるようにすることです。(これが意味することは、クラスは、さらにパラメーターを受け取るような型を期待する必要があるというSafeValueことです。次のように行うことができます。

class Safe s where
  check :: s a -> Bool
  (+++) :: s a -> s a -> s a
  make_new :: a ->  s a

次に、インスタンスは次のようになります。

instance Safe SafeValue where ...

重要な違いに注意してください。 for のインスタンスを作成する代わりに、型パラメータなしSafeValue aで for を作成しています。SafeValue

ただし、これには別の問題があります。現在aNumand Eq!

これは、マルチパラメーター型クラスと呼ばれる拡張機能で解決できます。したがって、最終バージョンは次のようになります。

class Safe s a where
  check :: s a -> Bool
  (+++) :: s a -> s a -> s a
  make_new :: a -> s a

インスタンスは次のようになります。

instance (Num a, Eq a) => Safe SafeValue a where ...

これらすべてを機能させるには、2 つの拡張機能を有効にする必要があります。

{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}

最初のものでは、より多くの方法でインスタンスを作成できます。T a b c通常、どこTが型でa b c型変数であるかのように見える型のインスタンスのみを記述できます。この拡張により、制限が解除され、私が示したようなインスタンスを作成できるようになります。

マルチパラメータ型クラス拡張により、複数の型に作用する型クラスが可能になります。s これにより、 と の両方に 依存するクラスを作成できますa

最後の注意: 型クラスをまったく使用することは、あなたの例にとって正しい選択ではないかもしれません。Safeクラスの型をさらに作成する予定はありますか? そうでない場合は、型クラスをまったく使用しないでください。ただし、マルチパラメーター型クラスについて少し学習することは依然として有用であるため、ある時点でそれらを試してみることを検討する必要があります。

于 2012-09-21T18:47:24.673 に答える