Eine solche Einschränkung führt zu einem Typfehler, wenn sie jemals als gegebene Einschränkung erscheint. Im Allgemeinen gilt dies für jede Einschränkung, die der Typchecker für unmöglich hält.
Schreiben auch eine Funktion
f :: ('True ~ 'False) => x
f = undefined
nicht funktioniert typecheck, weil der Kontext einer Funktion eine bestimmte Einschränkung im Körper der Funktion ist - und 'True ~ 'False
einfach nicht als gegebene Einschränkung erscheinen.
Im besten Fall könnten Sie z.B.
import Data.Type.Equality ((:~:)(..))
type family (==) (a :: k) (b :: k) :: Bool where
a == a = 'True
a == b = 'False
f :: ((x == y) ~ 'False) => x :~: y -> a
-- f Refl = undefined -- Inaccessible code
f = \case{}
wieder, die auf dem :~:
zurück zu einem EmptyCase
, diesmal kommt. Beachten Sie, dass
f :: ((x == y) ~ 'False, x ~ y) => a
auch ein trivialer unmöglich Einschränkung reduziert sich auf, weil x == x
zu True
reduziert. Sie könnten einen Gleichheitsvergleich schreiben, die nicht für trivialerweise gleich Typen nicht reduziert (zB die man in Data.Type.Equality
), die Sie schreiben kann:
import Data.Type.Equality
f :: ((x == y) ~ 'False, x ~ y) => Proxy '(x,y) -> a
f = undefined
es eine Möglichkeit sein kann, diese Funktion ohne undefined
zu schreiben, aber es ist Art strittig sowieso, da diese Art sofort von GHC reduziert:
>:t f
f :: forall (k :: BOX) (y :: k) a. ((y == y) ~ 'False) => Proxy '(y, y) -> a
ohne den Zwang
dort Auch ist es definitions unmöglich die Funktion Proxy '(y,y) -> a
mit zwei verschiedenen anrufen Arten. Es gibt keine Möglichkeit, eine Gleichheitsbedingung ~
aus dem Typchecker auszublenden - Sie müssen eine andere Form der Gleichheit verwenden, eine, die nicht auf ~
reduziert wird.
Ich bin kein Experte, aber ich denke, sobald eine Einschränkung keine Variablen enthält, versucht GHC, ein Wörterbuch/einen Beweis dafür zu erstellen. Wenn das fehlschlägt, wird ein Typfehler generiert. Es wäre interessant zu sehen, was passieren würde, wenn z.B. ''c' && Wahr :: Bool ~ Char => Bool ', so dass die Bedingung schwebt. Vielleicht ist die Fail-Early-Methode effizienter oder erzeugt bessere Fehler (?) – chi
Sie könnten 'EmptyCase' auf einem [' Dict'] (https://hackage.haskell.org/package/constraints-0.6/docs/Data- Constraint.html # g: 2). –