2016-03-21 11 views
0

folgende typeclass Betrachten Sie die Paare von Typen definiert:Standardwerte unterliegen existentielle Einschränkung in Haskell

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

Für alle Instanzen Einschränkung können wir eine Reihe von Typen ableiten a, im Wesentlichen eine implizite typeclass, nennen wir es A. Für jede Instanz der Typklasse A gibt es eine weitere implizite Typklasse B, die alle möglichen Typen b für Constraint A b enthält.

Also hier ist ein Stück 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 

Welche typechecks aber in GHCI

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

Aber

> 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) 

Nun ist die Art, wie ich es verstehe, ist, dass, da ich existentielle Typen verwenden, wird GHC wirklich nicht für die Art aussehen von answer, es stellt nur sicher, dass es einen geben könnte, selbst wenn es keine Möglichkeit hat herauszufinden, welcher es ist. Wenn ich dann also answer laufen lassen möchte, kann ich nicht herausfinden, wie ich damit umgehen soll.

Also meine Frage ist: Gibt es eine Möglichkeit, eine Standardantwort für jeden Typ zu definieren, die DefaultingQuestion

+3

Ich glaube nicht, das es sei denn, Sie arbeiten wird, möchte eine 'Typable' Einschränkung oder etwas hinzufügen. Können Sie einige konkrete Beispiele dafür nennen, warum Sie das wollen? – dfeuer

+0

Die 'Typable' (oder' Data') Einschränkung ist ein akzeptabler Kompromiss, aber ich konnte nicht herausfinden, wie es mit diesen Ereignissen zu tun ist ... – fakedrake

+2

Dieser Code ist so ... komisch ... das kann ich ' Geben Sie keinen konkreten Rat, ohne mehr Hintergrundwissen darüber zu haben, was Sie konkret erreichen möchten. Hast du einen Anwendungsfall? – dfeuer

Antwort

1

implementiert Warum nicht:

import Data.Proxy 

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

instance DefaultingQuestion A where 
    def _ = C1 
+0

Ja Proxy war genau die Art von was ich suchte – fakedrake