2014-11-04 4 views
3

Я пытаюсь написать модульный тест для простой функции, которая принимает список и просто возвращает егоТестирования функции, которая принимает пустой список

func :: [a] -> [a] 
func x = x 

используя тестовый код, чтобы проверить, что он работает как ожидается, когда данные пустому список

emptyListTest :: Test 
emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func [] 

main :: IO Counts 
main = runTestTT $ TestList [emptyListTest] 

Однако я получаю ошибку

No instance for (Show a0) arising from a use of `assertEqual' 
The type variable `a0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance Show Double -- Defined in `GHC.Float' 
    instance Show Float -- Defined in `GHC.Float' 
    instance (Integral a, Show a) => Show (GHC.Real.Ratio a) 
    -- Defined in `GHC.Real' 
    ...plus 28 others 
In the expression: assertEqual "for (func [])," [] 
In the second argument of `($)', namely 
    `assertEqual "for (func [])," [] $ func []' 
In the expression: 
    TestCase $ assertEqual "for (func [])," [] $ func [] 

других тесты с непустым литием sts работает нормально, и функция отлично работает при тестировании вручную, вызывая func [] в ghci.

Я также заметил, что если я создаю фиктивный тип и сделаю список, принимающий элементы этого типа (если это правильный способ сказать это), то передача этого теста, похоже, будет работать, а тест

data Dummy = Dummy 
    deriving(Eq, Show) 

emptyList :: [Dummy] 
emptyList = [] 

emptyListTest :: Test 
emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func emptyList 

Почему это? Есть ли способ проверить функции с пустым списком, не опуская путь фиктивного типа?

ответ

4

Ну, ошибка говорит вам точно, что не так. Прочтите.

The type variable `a0' is ambiguous 

Итак, введите свою переменную! GHC не может знать, какой тип использовать для тестирования, если вы этого не сделаете.

emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func ([] :: [Int]) 

Возможно, вам придется включить расширение, чтобы сделать его встроенным.

+0

Так почему же работа без ошибок в переводчике, когда я просто передать его '[]' без типа? –

+1

@Michal Charemza GHCI имеет специальные правила вывода. – alternative

+2

Чтобы быть более точным, ghci по умолчанию устанавливает ограничение '(Eq a, Show a)', связанное с ограничением 'assertEqual' на'() ', это расширение правил Haskell по умолчанию. См. [Здесь] (https://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluation.html#extended-default-rules) для получения более подробной информации! – yatima2975

1

Вам необходимо указать тип для пустого списка - иначе GHC не знает, какой список вы используете.

Одно из возможных решений:

.... assertEqual "for (func [])," [] $ func ([] :: [Int])