Выводимый тип недостаточно общий


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

prefix :: [a] -> [b] -> Bool
prefix [] _ = True
prefix _ [] = False
prefix (x:xs) (y:ys) = if (x==y) then prefix xs ys else False

Но он возвращает ошибку:

Inferred type is not general enough
*** Expression    : prefix
*** Expected type : [a] -> [b] -> Bool
*** Inferred type : [a] -> [a] -> Bool
Может кто-нибудь помочь мне заставить это работать?
2 2

2 ответа:

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

Это потому, что вы сравниваете типы, которые вы назвали a и b, используя (x==y). Проверка типа ==, что означает, что они одного типа, который имеет тест на равенство:

Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Таким образом, сигнатура типа, которая выводится, на самом деле является Eq a => [a] -> [a] -> Bool.