2

私はvinylを使用して、いくつかの異なるレコード タイプを宣言しています。その中にContentは、特定のタイプで呼び出されるフィールドがあるものもありますLanguageContent。レコードに存在するフィールドに依存する関数については、次のような型が必要です。

getContent :: HasContent a => a -> LanguageContent
getContent a = a ^. rlens SContent . unAttr

(説明のためだけに与えられた関数。何かを取得し、それを使用してさまざまなことを行う多くの関数がありますHasContent。)

HasContentここで、制約として宣言する必要があります。私が使用できる最も近いData.Vinyl.Notationものは次のとおりです。

getContent :: (Content ∈ fs) => Rec Attr fs -> LanguageContent

型ファミリは宣言できますが、関数は型チェックを行いません:

type family HasContent c :: Constraint
type instance HasContent (Rec Attr rs) = Content ∈ rs

getContent :: HasContent a => a -> LanguageContent
getContent a = a ^. rlens SContent . unAttr

Could not deduce (a ~ Rec Attr rs0)
from the context (HasContent a)

機能するが理想的ではない2つのパラメーターを使用して制約を作成できます(rsは、どこでも繰り返す必要があるパラメーターです)。

type HasContent c rs = (c ~ Rec Attr rs, Content ∈ rs)

追加のパラメーターがなければ (@ChristianConkle の回答を参照)、次のようになります。

type HasContent c = (c ~ Rec Attr rs, Content ∈ rs)

Not in scope: type variable ‘rs’

Rec Attr fsそのようなものだけに当てはまる制約を宣言するにはどうすればよいContent ∈ fsですか?

4

1 に答える 1