Изменить тип переменной в соответствии с ожидаемым типом - PullRequest
2 голосов
/ 13 марта 2019

В следующем коде я получаю сообщение об ошибке

Не удалось сопоставить тип 'Integer' с 'Int'
Ожидаемый тип: [(Test, [Test])]
Фактический тип: [(Integer, [Integer])]

при выполнении

testFunc test

со следующим объявлением

type TestType = Int
a = [(1,[2,3])]

testFunc :: [(TestType ,[TestType])] -> TestType 
testFunc ((a,(b:c)):d) = a

Как мне объявитьмой список a, чтобы он соответствовал типу testFunc?

И есть ли способ исправить ошибку без изменения type Test = Int или объявления a?

1 Ответ

4 голосов
/ 13 марта 2019

Как мне объявить мой список 'test', чтобы он соответствовал типу testFunc?

Хорошо, объявив его как тип.

a :: [(TestType, [TestType])]
a = [(1,[2,3])]

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

a :: (Num a, Num b) => [(a, [b])]

..., что будет включать в себя [(Int, [Int])] и [(Integer, [Integer])].Однако ограничение мономорфизма ограничивает тип по умолчанию, исключая такой полиморфизм.Таким образом, GHC должен выбрать одну версию, и по умолчанию это Integer, а не Int.

Опять-таки, правильное решение - предоставить явную подпись.Однако вы также можете отключить ограничение мономорфизма:

{-# LANGUAGE NoMonomorphismRestriction #-}

type TestType = Int
a = [(1,[2,3])]

testFunc :: [(TestType ,[TestType])] -> TestType 
testFunc ((x,(y:z)):w) = x

main :: IO ()
main = print $ testFunc a
...