2017-10-14 4 views
1

The following code génère une erreur « prévue une contrainte »:comment définir une classe avec un type de famille

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE ExistentialQuantification #-} 

type family Note a 
type instance Note String = String 

data SomeNote = forall a. Note a => SomeNote a 

class HasNote b where 
    noteOf :: b -> SomeNote 

L'erreur est Expected a constraint, but 'Note a' has kind '*', in the definition of SomeNote. Pourquoi ? Comment puis-je le réparer?

Le but est d'inclure une instance de la famille de type Note dans une structure de données b, et d'utiliser noteOf b pour l'extraire, quelle que soit l'instance.

Répondre

3

L'objectif est d'inclure une instance de la famille type de note dans une structure de données b, et utiliser noteOf b pour extraire

Ce n'est pas comment fonctionnent les familles de type. Tout ce que vous avez vraiment dit, c'est que vous pouvez mapper un type, représenté par la variable a dans un autre type via la fonction de type Note. Cela ne signifie pas que les valeurs de type a contiennent une valeur de type Note b. C'est la classe de type qui implique plutôt fortement que le type Note a est dans ou est calculable à partir du type a.

Le code est le long des lignes de:

type family Note a 
type instance Note String = String 
class SomeNote a where 
    noteOf :: a -> Note a 

Encore mieux, en utilisant un type associé:

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE FlexibleInstances #-} 

class SomeNote a where 
    type Note a :: * 
    noteOf :: a -> Note a 

instance SomeNote String where 
    type Note String = String 
    noteOf = id