Я озадачен тем, как компилятор haskell иногда запрашивает типы, которые меньше полиморфный, чем то, что я ожидал бы, например, при использовании точечных определений.
Похоже, проблема заключается в "ограничении мономорфизма", который по умолчанию включен более старые версии компилятора.
Рассмотрим следующую программу haskell:
{-# LANGUAGE MonomorphismRestriction #-}
import Data.List(sortBy)
plus = (+)
plus' x = (+ x)
sort = sortBy compare
main = do
  print $ plus' 1.0 2.0
  print $ plus 1.0 2.0
  print $ sort [3, 1, 2]
Если я скомпилирую это с помощью ghc, я не получаю erros, а вывод исполняемого файла:
3.0
3.0
[1,2,3]
Если я изменил тело main на:
main = do
  print $ plus' 1.0 2.0
  print $ plus (1 :: Int) 2
  print $ sort [3, 1, 2]
Я не получаю ошибок времени компиляции, и результат становится:
3.0
3
[1,2,3]
как ожидалось. Однако, если я попытаюсь изменить его на:
main = do
  print $ plus' 1.0 2.0
  print $ plus (1 :: Int) 2
  print $ plus 1.0 2.0
  print $ sort [3, 1, 2]
Я получаю ошибку типа:
test.hs:13:16:
    No instance for (Fractional Int) arising from the literal ‘1.0’
    In the first argument of ‘plus’, namely ‘1.0’
    In the second argument of ‘($)’, namely ‘plus 1.0 2.0’
    In a stmt of a 'do' block: print $ plus 1.0 2.0
То же самое происходит при попытке дважды вызвать sort с разными типами:
main = do
  print $ plus' 1.0 2.0
  print $ plus 1.0 2.0
  print $ sort [3, 1, 2]
  print $ sort "cba"
выдает следующую ошибку:
test.hs:14:17:
    No instance for (Num Char) arising from the literal ‘3’
    In the expression: 3
    In the first argument of ‘sort’, namely ‘[3, 1, 2]’
    In the second argument of ‘($)’, namely ‘sort [3, 1, 2]’
-  Почему 
ghcвдруг думает, чтоplusне является полиморфным и требует аргументInt? Единственная ссылка наIntнаходится в приложенииplus, как это может иметь значение когда определение явно полиморфно? -  Почему 
ghcвдруг думает, чтоsortтребуется экземплярNum Char? 
Более того, если я попытаюсь поместить определения функций в их собственный модуль, как в:
{-# LANGUAGE MonomorphismRestriction #-}
module TestMono where
import Data.List(sortBy)
plus = (+)
plus' x = (+ x)
sort = sortBy compare
При компиляции я получаю следующую ошибку:
TestMono.hs:10:15:
    No instance for (Ord a0) arising from a use of ‘compare’
    The type variable ‘a0’ is ambiguous
    Relevant bindings include
      sort :: [a0] -> [a0] (bound at TestMono.hs:10:1)
    Note: there are several potential instances:
      instance Integral a => Ord (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      instance Ord () -- Defined in ‘GHC.Classes’
      instance (Ord a, Ord b) => Ord (a, b) -- Defined in ‘GHC.Classes’
      ...plus 23 others
    In the first argument of ‘sortBy’, namely ‘compare’
    In the expression: sortBy compare
    In an equation for ‘sort’: sort = sortBy compare
-  Почему 
ghcне может использовать полиморфный типOrd a => [a] -> [a]дляsort? -  И почему 
ghcобрабатываетplusиplus'по-другому?plusдолжен иметь полиморфный типNum a => a -> a -> a, и я действительно не вижу, как это отличается от типаsort, но толькоsortвызывает ошибку. 
Последняя вещь: если я комментирую определение sort, файл компилируется. Однако
если я попытаюсь загрузить его в ghci и проверить типы, которые я получаю:
*TestMono> :t plus
plus :: Integer -> Integer -> Integer
*TestMono> :t plus'
plus' :: Num a => a -> a -> a
Почему тип plus не является полиморфным?
Это канонический вопрос об ограничении мономорфизма в Haskell как обсуждалось в мета-вопросе.