2017-06-04 12 views
0

これは本当に簡単なはずですが、私はかなりの時間この時点で固執しています。データ型のリストのインスタンスを作成する - Haskell

haskellでは、特定のデータ型のリストの型クラスのインスタンスを作成できますか?

私が達成したいことは次のとおりです。私はこの問題を解決する方法を知っていただきたいと思います、なぜこれが許可されていない

* Illegal instance declaration for `Rename [Atom]' 
     (All instance types must be of the form (T a1 ... an) 
     where a1 ... an are *distinct type variables*, 
     and each type variable appears at most once in the instance head. 
     Use FlexibleInstances if you want to disable this.) 
    * In the instance declaration for `Rename ([] Atom)' 
Failed, modules loaded: none. 

:どのようにこれまで私はこれを書いたとき、私は次のエラーを取得する

class Rename a where 
    findSub :: a -> a 

-- A 'normal' instance would look like this 
instance Rename Atom where 
    findSub ...... 

-- Now i want to acchieve something like this 
instance Rename ([] Atom) where 
    findSub ...... 

ありがとうございます。

答えて

3

この形式のインスタンスは、Haskell 98標準では技術的に許可されていないため、言語拡張が必要です。拡張機能を有効にするというエラーメッセージが表示されたら、通常はそれを実行します[1]。 FlexibleInstancesはこれだけ、ファイルの先頭に

{-# LANGUAGE FlexibleInstances #-} 

を入れて、非常に一般的と認められた拡張機能です。


タイプは、より一般的であるため、また、しばしばそのような場合は、拡張子を必要としない場合には、「再帰的」に定義することができますが、それ以外にも、あなたが自由に、そしてより多くの保証のための複数のインスタンスを取得します。あなたはaRenameではなく、それが特異的Atomされていることを事実のみを使用して、代わりに

instance (Rename a) => Rename [a] where 
    findSub ... 

を定義することができます参照してください。このようにインスタンスを定義することができれば、設計が適切な軌道上にあることを示す良い兆候です。


[1]、時にはあなたは型クラスの解像度がどのように機能するかについての間違った考えを持っていることを示しているようにUndecidableInstancesIncoherentInstancesなど、いくつかの例外が、あります。

+0

「UndecidableInstances」が間違ったコードで表示されることはありません。私は、Haskellの非常に限定された終了基準が良いことを証明するには不十分であることを、完全に優れたコードではるかに見る傾向があります。 – dfeuer

+0

@dfeuer、私は同意しますが、初心者はtypeclassの解像度を後ろ向きに考えたり、はるかに強力である(たとえば、 'インスタンスベクトルa => Num a'など)傾向があります。これらの拡張機能がすぐに「必要」になります(有効にしても、意図したとおりに機能しません)。いいえ? – luqui

+0

私は、 'OverlappingInstances'、' IncoherentInstances'、 'AllowAmbiguousTypes'、および(マルチパラメータ型クラスを使用していないとき)' FlexibleInstances'についてもっと考えると思います。しかし、あなたは正しいかもしれません。 – dfeuer

関連する問題