Как работать с assertEqual с параметризованными типами - PullRequest
3 голосов
/ 14 сентября 2009

Я пытаюсь выполнять упражнения в реальном мире на Haskell в стиле TDD, используя HUnit . Как вы, наверное, догадались, я еще далеко не добрался, поэтому я абсолютный новичок в том, что касается Хаскелла. Учитывая следующий код, как я могу решить следующую ошибку, которую выдает ghci:

Переменная двусмысленного типа a' in the constraints: Показывать ' в результате использования assertEqual' at List_Test.hs:6:27-58 Eq a ', возникающего в результате использования `assertEqual' в List_Test.hs: 6: 27-58 Возможное исправление: добавьте сигнатуру типа, которая исправляет эти переменные типа

List_Test.hs:

module List_Test
where
import List
import Test.HUnit

fromEmptyList = TestCase $ assertEqual "" [] (toList (Nil))

main = runTestTT fromEmptyList

List.hs:

module List
where
data List a = Cons a (List a)
            | Nil
              deriving (Show)

toList Nil = []
toList (Cons a b) = (:) a (toList b) 

Я безуспешно пытался добавить ограничения типа в объявление List и определение toList. Поиск в Интернете также не дал никакой информации.

1 Ответ

6 голосов
/ 14 сентября 2009

Частично проблема в том, что GHC не знает, что toList Nil вернет пустой список.

*List> :i toList
toList :: List a -> [a]     -- Defined at List.hs:7:0-5

Он только знает, что вернет список типа a, но не знает, что такое a - отсюда и сообщение «переменная неоднозначного типа a». Один из способов обойти это - просто указать тип списка, который будет возвращать toList:

fromEmptyList = TestCase $ assertEqual "" [] (toList (Nil) :: [Int])

Изменение этого и удаление первых двух строк List_Test (он не будет искать функцию main в именованном модуле, который не назван Main), дал мне такой результат:

$ runghc List_Test.hs 
Cases: 1  Tried: 1  Errors: 0  Failures: 0
...