2016-03-21 1 views
0

Tenir compte des classe de types suivants qui définissent des paires de types:Les valeurs par défaut soumises à des contraintes existentielles dans haskell

class Constraint a b where 
    g :: a -> b 

Pour tous les cas de contrainte, nous pouvons en déduire un ensemble de types a, essentiellement une classe de types implicite, appelons-le A. Pour chaque instance de classe de type A, il existe une autre classe de type implicite B qui inclut tous les types possibles b pour Constraint A b.

Voici donc un bout de code.

{-# LANGUAGE ExistentialQuantification #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
import Debug.Trace 

-- Contraining class 
class (Show a, Show b) => QandA a b where 
    g :: a -> b 

-- Some data types 
data A = A1 | A2 deriving (Show, Eq) 
data B = B1 | B2 deriving (Show, Eq) 
data C = C1 | C2 deriving (Show, Eq) 

instance QandA A B where 
    g A1 = B1 
    g A2 = B2 

instance QandA A C where 
    g A1 = C1 
    g A2 = C2 

-- We want to define a set of types that includes all the types that 
-- have Constraint a b given a. This can be done via an intermediate 
-- type. 
data DefaultAnswer q = forall a . (DefaultingQuestion q, QandA q a) => DefaultAnswer {answer :: a}; 

-- Polymorphism 
class DefaultingQuestion q where 
    def :: DefaultAnswer q 

instance DefaultingQuestion A where 
    def = DefaultAnswer C1 

qui typable mais dans ghci

> (def :: DefaultAnswer A) 
(def :: DefaultAnswer A) :: DefaultAnswer A 

Mais

> answer (def :: DefaultAnswer A) 
<interactive>:574:1: 
    Cannot use record selector "answer" as a function due to escaped type variables 
    Probable fix: use pattern-matching syntax instead 
    In the expression: answer (def :: DefaultAnswer A) 
    In an equation for "it": it = answer (def :: DefaultAnswer A) 

Maintenant, la façon dont je comprends est que, depuis que j'utilise les types existentiels, GHC ne regarde pas vraiment le type de answer, il s'assure juste qu'il pourrait y en avoir un même s'il n'a aucun moyen de déterminer lequel il est. Alors, quand je veux réellement courir answer il ne peut pas comprendre comment faire face à cela.

Ma question est: est-il un moyen de définir une réponse par défaut pour chaque type qui implémente DefaultingQuestion

+3

Je ne pense pas que cela va fonctionner, à moins que vous vouloir ajouter une contrainte 'Typeable' ou quelque chose. Pouvez-vous donner des exemples concrets de pourquoi vous voulez cela? – dfeuer

+0

La contrainte 'Typeable' (ou' Data') est un compromis acceptable, mais je ne pouvais pas comprendre comment faire l'événement avec ceux-ci ... – fakedrake

+2

Ce code est tellement ... bizarre ... que je peux ' t donner des conseils concrets sans plus de contexte sur ce que, concrètement, vous essayez d'accomplir. Avez-vous un cas d'utilisation? – dfeuer

Répondre

1

Pourquoi ne pas:

import Data.Proxy 

class DefaultingQuestion q a where 
    def :: Proxy q -> a 

instance DefaultingQuestion A where 
    def _ = C1 
+0

Oui proxy était exactement le genre de chose que je cherchais – fakedrake