Преобразование функции в бесшумный стиль меняет свой тип
Я начинаю Haskell... Я попытался написать следующую тривиальную функцию двумя разными способами, позволяя Haskell решать типы, а система типов делает что-то другое в каждом случае. Каково объяснение этого поведения?
Prelude> let f x = 2 * x
Prelude> let g = (2*)
Prelude> :info f
f :: Num a => a -> a -- Defined at <interactive>:1:5
Prelude> :info g
g :: Integer -> Integer -- Defined at <interactive>:1:5
Спасибо!
Ответы
Ответ 1
Это называется ограничение мономорфизма.
В основном это означает, что привязки верхнего уровня, которые выглядят как x =
, вынуждены быть неполиморфными, если вы не укажете подпись типа. Привязки с аргументами, т.е. f x =
, не затрагиваются. См. Ссылку, чтобы узнать, почему это ограничение существует.
Обычно вы получаете сообщение об ошибке, когда применяется ограничение, но в этом случае GHCi может использовать тип по умолчанию для изменения типа Num a => a
на Integer
.
Самый простой способ уклониться от него - либо использовать явную подпись типа, либо поставить
{-# LANGUAGE NoMonomorphismRestriction #-}
в верхней части вашего модуля или запустите GHCi с помощью -XNoMonomorphismRestriction
.
Ответ 2
Как указывали другие, это вызвано тем, что называется "Ограничением мономорфизма".
MR может быть полезен для писателей компиляторов Haskell, и есть споры о том, стоит ли вообще иметь на языке вообще. Но есть одна вещь, с которой все согласны: в приглашении GHCi MR - не что иное, как неприятность.
MR, вероятно, будет отключен по умолчанию в этом контексте в предстоящей версии GHC. На данный момент вы должны отключить его в GHCi, создав в своем домашнем каталоге текстовый файл с именем ".ghci
", который содержит следующую строку:
:set -XNoMonomorphismRestriction
Ответ 3
Поскольку определение g
явно не указывает его аргументы, вы выполняете ограничение мономорфизма, предотвращая g
от полиморфный и (в этом случае), вызывающий GHC по умолчанию Integer
.