2013-03-16 4 views
7

играя в ghci я получил следующее выражение: unlines . map (\(a,b) -> show a ++ " " ++ show b)Почему изменение подписи после присвоения

Теперь, когда я проверить его с помощью :t я получаю:

> :t unlines . map (\(a,b) -> show a ++ " " ++ show b) 
unlines . map (\(a,b) -> show a ++ " " ++ show b) 
    :: (Show a, Show a1) => [(a, a1)] -> String 

Так точно, как и ожидалось. Но теперь, если я стараюсь, чтобы назначить его на некоторое имя, я получаю более конкретную сигнатуру, чем оригинал:

> let f = unlines . map (\(a,b) -> show a ++ " " ++ show b) 
> :t f 
f :: [((),())] -> String 

Почему это происходит?

+1

См. Также: [1] (http://stackoverflow.com/questions/7055146), [2] (http://stackoverflow.com/questions/11439163), [3] (http: // stackoverflow. com/questions/9714697), [4] (http://stackoverflow.com/questions/8434808), [5] (http://stackoverflow.com/questions/7799345), [6] (http: // stackoverflow .com/questions/8262020), [7] (http://stackoverflow.com/questions/8655900), [8] (http://stackoverflow.com/questions/11003535). Я честно не знаю, какой из них (если есть), чтобы отметить это дубликат. –

ответ

12

Из-за monomorphism restriction, определение формы x = ... (без параметров) приведены мономорфного (т.е. не-полиморфного) типа, который обычно включает в себя некоторые недобросовестном, как упоминалось in the other answer.

Чтобы предотвратить это, добавьте подпись типа к вашему определению или отключите ограничение мономорфизма с помощью :set -XNoMonomorphismRestriction. Вы можете добавить это в свой .ghci file, чтобы он запускался автоматически при запуске до it gets disabled by default in GHCi in some future version.

+1

or eta expand; то есть 'let f x = unlines. map (\ (a, b) -> показать ++ "" ++ show b) $ x' – luqui

4

Неверные правила.

Когда вы вводите материал в GHCi, он пытается применить типы по умолчанию. IIRC, для вещей с ограничением Num он выбирает Integer, для Fractional он выбирает Double, а для всего остального он выбирает ().

Если вы пишете это в исходном файле Haskell и загрузите его в GHCi, этого не произойдет (я считаю).

Я думаю, вы также можете сказать что-то вроде default Int, чтобы изменить правила по умолчанию для каждого модуля.

Смежные вопросы