52700.fb2
( MR. hs, interpreted )
MR. hs:4:7:
Ambiguous type variable ‘a0’ in the constraint:
(Eq a0) arising from a use of ‘==’
Possible cause: the monomorphism restriction applied to the following:
eq :: a0 -> a0 -> Bool (bound at MR.hs:4:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction
In the expression: (==)
In an equation for ‘eq’: eq = (==)
Failed, modules loaded: none.
Компилятор жалуется о том, что в определении для eq ему встретилась неопределённость и он не смог
вывести тип. Если же мы допишем недостающие типы:
module MR where
add :: Num a => a -> a -> a
add = (+)
eq :: Eq a => a -> a -> Bool
eq
= (==)
то всё пройдёт гладко:
Prelude> :l MR
[1 of 1] Compiling MR
( MR. hs, interpreted )
Ok, modules loaded: MR.
*MR> eq 2 3
False
Но оказывается, что если мы допишем аргументы у функций и сотрём объявления, компилятор сможет
вывести тип, и тип окажется общим. Это можно проверить в интерпретаторе. Для этого начнём новую сессию:
Prelude> let eq a b = (==) a b
Prelude> :t eq
eq :: Eq a => a -> a -> Bool
Prelude> let add a = (+) a
Prelude> :t add
add :: Num a => a -> a -> a
Запишите эти выражения в модуле без типов и попробуйте загрузить. Почему так происходит? По смыслу
определения
add a b = (+) a b
add
= (+)
ничем не отличаются друг от друга, но второе сбивает компилятор столку. Компилятор путается из-
за того, что второй вариант похож на определение константы. Мы с вами знаем, что выражение справа от
знака равно является функцией, но компилятор, посчитав аргументы слева от знака равно, думает, что это
возможно константа, потому что она выглядит как константа. У таких возможно-констант есть специальное
имя, они называются константными аппликативными формами (constant applicative form или сокращённо
CAF). Константы можно вычислять один раз, на то они и константы. Но если тип константы перегружен,
и мы не знаем что это за тип (если пользователь не подсказал нам об этом в объявлении типа), то нам
приходится вычислять его каждый раз заново. Посмотрим на пример:
Проверка типов | 53
res = s + s