Ich fummle mit Haskell herum, aber ich kämpfe mit einem Problem. Der folgende Code:Der erwartete Typ 'r' konnte nicht mit dem tatsächlichen Typ 'Pferd' verglichen werden.
class HasHorses e where yieldInHorses :: (InHorses r) => e -> r
class InHorses e
data Horse = Horse String
data Stable = Stable String
instance InHorses Horse
instance HasHorses Stable where yieldInHorses e = (Horse "Buttercup")
gibt mir die folgende Fehlermeldung:
source_file.hs:10:52: error:
• Couldn't match expected type ‘r’ with actual type ‘Horse’
‘r’ is a rigid type variable bound by
the type signature for:
yieldInHorses :: forall r. InHorses r => Stable -> r
at source_file.hs:10:33
• In the expression: (Horse "Buttercup")
In an equation for ‘yieldInHorses’:
yieldInHorses e = (Horse "Buttercup")
In the instance declaration for ‘HasHorses Stable’
• Relevant bindings include
yieldInHorses :: Stable -> r
(bound at source_file.hs:10:33)
Wo Linie 10 zur Linie bezieht, in dem ich instance HasHorses Stable where ...
.
Vielleicht habe ich etwas übersehen, aber ich kann nicht sehen, warum dies ein Fehler sein sollte. Das tatsächliche Type Horse erfüllt die Bedingung von r, nämlich dass es InHorses sein sollte.
Die Idee der 'yieldInHorses' Methode ist, dass für etwas, das HasHorses, Aufruf dieser Methode darauf sollte mir sagen, die Pferde (nun, Pferd, um zu beginnen - Dies wird Listen bald umfassen), dass es hat.
Habe ich einen einfachen Fehler gemacht oder etwas grundlegenderes falsch verstanden?
Die Art der 'yieldInHorses' ist eigentlich' forall r. InHorse r => e -> r', was vor allem bedeutet, dass der * Caller entscheiden muss, was "r" sein soll. Was du suchst, ist etwas wie 'exists' anstatt' forall', was in Haskell nicht direkt verfügbar ist, obwohl [es ist möglich, etwas wie sie mit anderen Konstrukten zu kodieren] (https://wiki.haskell.org/ Existential_type). Dies ist jedoch ein so konstruiertes Beispiel, dass es schwierig ist, konkrete Ratschläge zu geben - warum würden Sie jemals eine Typenklasse wie "InHorses" brauchen? –
Anstelle von 'InHorses r => e -> r 'benutzen Sie einfach' e -> Horses', wobei 'Horses 'ein Typ ist, der alle gewünschten Informationen korrekt aufnimmt, wahrscheinlich' [Horse] '. – user2407038
Ich frage mich, warum Sie Typklassen verwenden. Brauchst du sie wirklich? Wenn eine Typklasse nur genau eine Instanz hat, sollten Sie sie wahrscheinlich verwerfen und direkt den einfachen Typ verwenden. – chi