Ошибка в ghci, которую я не могу воспроизвести в письменном файле haskell

Я попытался проверить этот ответ stackru с помощью ghci и получить следующую ошибку:

> import Data.List
> let m = head . sort
> m [2,3,4]

<interactive>:5:4:
   No instance for (Num ()) arising from the literal `2'
   Possible fix: add an instance declaration for (Num ())
   In the expression: 2
   In the first argument of `m', namely `[2, 3, 4]'
   In the expression: m [2, 3, 4]

К сожалению, я не могу воспроизвести ошибку в письменном файле haskell:

-- file.hs
import Data.List

main = do
    let m = head . sort
    putStrLn $ show $ m [2,3,4]

Запуск этого файла с runhaskell file.hs дает мне ожидаемое значение 2, В чем моя ошибка в сеансе ghci?

Редактировать: я отметил, что функция m имеет странный тип в GHCI:

> import Data.List
> let m = head . sort
> :t m
m :: [()] -> ()

Почему это так? Разве это не имеет тип Ord a => [a] -> a? За sort а также head Я получаю ожидаемые типы:

> :t sort
sort :: Ord a => [a] -> [a]
> :t head
head :: [a] -> a

1 ответ

Решение

Это вина страшного ограничения мономорфизма. В основном, потому что вы не указали тип для mGHCi угадывает это для вас. В этом случае он догадывается, что m должен иметь тип [()] -> ()даже если это явно не то, что вы хотите. Просто дай m подпись типа в GHCi и у тебя все будет хорошо.

> :set +m  -- multiline expressions, they're handy
> let m :: Ord a => [a] -> a
|     m = head . sort

Вы можете отключить ограничение мономорфизма с

> :set -XNoMonomorphismRestriction

Но это обычно довольно удобно, в противном случае вам придется указывать множество типов для вещей, которые вы обычно не делаете в интерактивном режиме.

Другие вопросы по тегам