2016-02-28 1 views
3

Je comprends que je peux promouvoir Bool au niveau du genre comme si, où Bool peut potentiellement être True ou False:type de données qui est promouvables au niveau du genre avec une seule valeur

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE TypeFamilies #-} 

type family TF t :: Bool 
type instance TF Int = True 
type instance TF Bool = False 

Je voulais plutôt promouvoir () , qui bien sûr n'a qu'une valeur (). Mais cela ne semble pas fonctionner:

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE TypeFamilies #-} 

type family TF t ::() 
type instance TF Int =() 
type instance TF Bool =() 

Je suppose que je pourrais simplement utiliser Bool et True, mais est-il un seul type d'une valeur qui peut être promu au niveau de la nature?

Répondre

6

Essayez utilisation '() au lieu de () au niveau du type:

type family ToNull t ::() 
type instance ToNull Int = '() 
type instance ToNull Bool = '() 

également True et False sont en fait pour 'True et sténographies 'False au niveau du type.

Le problème est il y a quatre () dans le cadre:

  1. le type ordinaire () de type *
  2. le seul constructeur de 1 qui est également ()
  3. le genre () promu de 1
  4. le type '() du type () promu de 2, qui a un synonyme de type () par défaut

sans la guillemets simples parfois optionnels, 1 et 4 sont ambigus.

Vous pouvez consulter le guide utilisateur de GHC pour plus de détails: 7.9. Datatype promotion

+0

Merci. Juste curieux, est-ce que "True" et "False" sont magiques ou est-ce que je peux définir '()' de même? – Clinton

+0

@Clinton 'True' et' False' sont des synonymes de '' True'' et ''False', définis par l'extension' DataKinds' pour plus de commodité. C'est bon pour Bool mais quand le type et le constructeur ont le même nom il y a ambiguïté, donc le guillemet simple habituellement optionnel est nécessaire. – zakyggaps

+3

Il y a même un cinquième '()' pour une confusion supplémentaire: la contrainte vide. – dfeuer