Преобразование функции в бесшумный стиль меняет свой тип

Я начинаю 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.