Ich begann mit 99 Haskell-Problemen und ich war auf Problem 7 und meinen Unittests explodierten.
Anscheinend liegt das daran: Ссылка
Ich wollte nur sichergehen, dass ich das richtig verstanden habe, weil ich irgendwie verwirrt bin.
Situation 1: func a
wird ohne Typ def oder mit einem nicht strikten Typ def definiert und dann einmal verwendet. Der Compiler hat keine Probleme, den Typ zur Kompilierzeit abzuleiten.
Situation 2: das gleiche func a
wird oft im Programm verwendet, der Compiler kann nicht zu 100% sicher sein, was der Typ ist, wenn er die Funktion für die gegebenen Argumente nicht erneut berechnet.
Um den Rechenverlust zu vermeiden, beschwert sich ghc beim Programmierer, dass es einen strikten Typ def benötigt a
um richtig zu funktionieren.
Ich denke, in meiner Situation hat assertEqual
den Typ def von
Ich bekam einen Fehler, als test3
definiert wurde, was ich interpretierte, dass es 2 mögliche Typen für die Rückgabe von testcase3
(Show und Eq) gab und nicht wusste, wie ich weitermachen soll.
Klingt das richtig oder bin ich komplett ausgeschaltet?
problem7.hs:
%Vor% 1. Situation: testcase3 = flatten (List [])
Zweite Situation: testcase3 = flatten (List []) :: Eq a => [a]
Es ist nicht so sehr die Monomorphie-Einschränkung, es ist die Auflösung von mehrdeutigen Variablen durch säumig , die den Kompilierungsfehler verursacht.
%Vor% flatten
erzwingt keine Einschränkungen für die Typvariable a
, es gibt also kein Problem mit der Definition von testcase3
als solcher, es wäre polymorph.
Aber wenn Sie es in test3
verwenden,
Sie erben die Einschränkungen von
%Vor% Nun muss der Compiler herausfinden, an welchem Typ testcase3
verwendet werden soll. Es gibt nicht genügend Kontext, um den Typ zu bestimmen, daher versucht der Compiler standardmäßig, die Typvariable aufzulösen. Gemäß den Standardregeln kann ein Kontext (Eq a, Show a)
nicht standardmäßig aufgelöst werden , da nur Kontexte berücksichtigt werden können, die mindestens eine numerische Klasse enthalten. Daher schlägt die Kompilierung aufgrund einer mehrdeutigen Variablen fehl.
testcase3'
und testcase3''
fallen jedoch aufgrund der Signatur des Ausdruckstyps unter die Monomorphie-Einschränkung, die der rechten Seite der Definition Beschränkungen auferlegt, die von der linken geerbt werden.
testcase3'
kann daher nicht kompiliert werden, unabhängig davon, ob es in einer Assertion verwendet wird.
testcase3''
wird standardmäßig auf [Integer]
zurückgesetzt, da die Signatur des Ausdruckstyps eine numerische Einschränkung auferlegt. Wenn der Typ für testcase''
monomorphisiert wird, wird daher die Variable des eingeschränkten Typs standardmäßig auf Integer
gesetzt. Dann ist der Typ, in dem es in test3
verwendet wird, keine Frage.
Wenn Sie den Bindungen Typensignaturen anstatt auf der rechten Seite gegeben hätten,
%Vor% beide Werte hätten sich selbst zu polymorphen Werten kompiliert, aber immer noch wäre nur testcase3''
in test3
verwendbar, da nur dadurch die erforderliche numerische Integritätsbedingung eingeführt wird, um Standardwerte zuzulassen.
Tags und Links haskell monomorphism-restriction