Hier ist das Szenario: Ich habe Code mit einer Typensignatur geschrieben und GHC-Beschwerden konnten für einige x
und nicht auf x ~ y schließen y
. Normalerweise können Sie GHC einen Knochen werfen und einfach den Isomorphismus zu den Funktionseinschränkungen hinzufügen. Dies ist jedoch aus mehreren Gründen eine schlechte Idee:
- Das Verständnis des Codes wird nicht betont.
- Sie können mit 5 Einschränkungen enden, bei denen eine ausreichend gewesen wäre (z. B. wenn die 5 durch eine spezifischere Einschränkung impliziert werden).
- Sie können mit falschen Einschränkungen enden, wenn Sie etwas falsch gemacht haben oder wenn GHC nicht hilfreich ist
Ich habe gerade einige Stunden mit Fall 3 gekämpft. Ich spiele mit syntactic-2.0
und habe versucht, eine domänenunabhängige Version von zu definieren share
, ähnlich der in definierten Version NanoFeldspar.hs
.
Ich hatte das:
{-# LANGUAGE GADTs, FlexibleContexts, TypeOperators #-}
import Data.Syntactic
-- Based on NanoFeldspar.hs
data Let a where
Let :: Let (a :-> (a -> b) :-> Full b)
share :: (Let :<: sup,
Domain a ~ sup,
Domain b ~ sup,
SyntacticN (a -> (a -> b) -> b) fi)
=> a -> (a -> b) -> a
share = sugarSym Let
und GHC could not deduce (Internal a) ~ (Internal b)
, was ich sicherlich nicht wollte. Entweder hatte ich Code geschrieben, den ich nicht beabsichtigt hatte (für den die Einschränkung erforderlich war), oder GHC wollte diese Einschränkung aufgrund einiger anderer Einschränkungen, die ich geschrieben hatte.
Es stellte sich heraus, dass ich zur (Syntactic a, Syntactic b, Syntactic (a->b))
Einschränkungsliste hinzufügen musste , von denen keine impliziert (Internal a) ~ (Internal b)
. Ich bin im Grunde auf die richtigen Einschränkungen gestoßen; Ich habe immer noch keinen systematischen Weg, sie zu finden.
Meine Fragen sind:
- Warum hat GHC diese Einschränkung vorgeschlagen? Nirgendwo in der Syntaktik gibt es eine Einschränkung
Internal a ~ Internal b
. Woher hat GHC diese? - Welche Techniken können im Allgemeinen verwendet werden, um den Ursprung einer Einschränkung zu verfolgen, die GHC für erforderlich hält? Selbst für Einschränkungen, die ich selbst entdecken kann, ist mein Ansatz im Wesentlichen brutal, den beleidigenden Pfad zu erzwingen, indem ich rekursive Einschränkungen physisch aufschreibe. Dieser Ansatz geht im Grunde genommen durch ein unendliches Kaninchenloch von Zwängen und ist ungefähr die am wenigsten effiziente Methode, die ich mir vorstellen kann.
a
und b
gebunden - schauen Sie sich die Typensignatur außerhalb Ihres Kontexts an - a -> (a -> b) -> a
nicht a -> (a -> b) -> b
. Vielleicht ist es das? Mit Constraint-Solvern können sie die transitive Gleichheit überall beeinflussen , aber die Fehler zeigen normalerweise einen Ort "nahe" an dem Ort, an dem die Constraint induziert wurde. Das wäre aber cool, @jozefg - vielleicht Einschränkungen mit Tags oder so etwas zu kommentieren, um zu zeigen, woher sie kommen? : s