2017-07-22 3 views
1

J'ai rencontré un comportement bizarre HUnit. Il ne permet pas de compiler les cas de test si la condition Nothing == Nothing est présente dans le test. Voici mon code qui reproduit ce comportement:HUnit ne permet pas de compiler des cas de test si la condition `Nothing == Nothing` est présente dans le test

module TestTest where 

import Control.Exception 
import Control.Monad 
import Test.HUnit 
import Test.AssertError 

testTests = test [ 
    "test A01" ~: "x == x" ~: True ~=? Nothing == Nothing, 
    "test _" ~: "empty test" ~: True ~=? True 
    ] 

runTests :: IO Counts 
runTests = do 
    runTestTT testTests 

tente de charger le fichier avec ce contenu en ghci suivant renvoie l'erreur:

[2 of 2] Compiling TestTest   (Test/TestTest.hs, interpreted) 

Test/TestTest.hs:9:49: 
    No instance for (Eq a0) arising from a use of ‘==’ 
    The type variable ‘a0’ is ambiguous 
    Note: there are several potential instances: 
     instance Eq Counts -- Defined in ‘Test.HUnit.Base’ 
     instance Eq Node -- Defined in ‘Test.HUnit.Base’ 
     instance Eq State -- Defined in ‘Test.HUnit.Base’ 
     ...plus 53 others 
    In the second argument of ‘(~=?)’, namely ‘Nothing == Nothing’ 
    In the second argument of ‘(~:)’, namely 
     ‘True ~=? Nothing == Nothing’ 
    In the second argument of ‘(~:)’, namely 
     ‘"x == x" ~: True ~=? Nothing == Nothing’ 
Failed, modules loaded: Test.AssertError. 

Notez que la condition Just 2 == Just 2 dans le même cas de test fonctionne très bien. Si je tape Nothing == Nothing dans ghci, il renvoie True comme prévu.

Des idées pour lesquelles HUnit pourrait se comporter de cette façon? Est-ce un bug ou un comportement attendu?

+0

Vous devez spécifier le type de 'Maybe a'. –

Répondre

3

Le problème est que vous spécifiez deux Nothing s, et aucun de ceux-ci n'indique donc quel sera le type de a. Bien sûr, vous pouvez raisonner que pour Nothing ce n'est pas grave. Mais Haskell ne raisonne pas de cette façon: il s'intéresse à "à quelle fonction devrais-je pointer?".

Vous pouvez résoudre le problème en rendant le type explicite. Par exemple:

testTests = test [ 
    "test A01" ~: "x == x" ~: True ~=? (Nothing :: Maybe Int) == Nothing, 
    "test _" ~: "empty test" ~: True ~=? True 
    ]
+0

Pourquoi alors l'exécution de 'Nothing == Nothing' dans' ghci' retourne 'True' sans spécifier explicitement le type entier? – altern

+0

@altern: car 'ghci' diffère le type de mise à la terre. Tout simplement parce qu'il ne peut pas le faire immédiatement. 'ghc' va interpréter tous les fichiers et ensuite raisonner sur ceux-ci. –

+7

@altern En raison de [extended defaulting] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#extended-default-rules), qui choisit des types monomorphes dans des situations de type ambigu plus souvent, et qui est activé par défaut dans ghci et désactivé par défaut ailleurs. –