Я озадачен, казалось бы, ошибочным поведением GHC, происходящим с довольно простыми программами на Haskell.
Рассмотрим следующий код:
import System.IO
output :: [String] -> IO()
output stringList = sequence_ $ map putStrLn stringList
main :: IO ()
s = show
main = output [
s 42,
s True
]
В GHC 8.4.3 выдает следующий вывод:
$ runghc parameterize.hs
.hs:9:7: error:
• No instance for (Num Bool) arising from the literal ‘42’
• In the first argument of ‘s’, namely ‘42’
In the expression: s 42
In the first argument of ‘output’, namely ‘[s 42, s True]’
|
9 | s 42,
|
GHC 8.0.2 выдает ту же ошибку.
Это также происходит со следующими вариантами:
Использование where
main :: IO ()
main = output [
s 42,
s True
]
where s = show
Использование let ... in
main :: IO ()
main = let s = show in output [
s 42,
s True
]
Но в трех случаях замена s = show
на s x = show x
решает проблему:
main :: IO ()
s x = show x
main = output [
s 42,
s True
]
$ runghc u.hs
42
True
Это не относится только к show
.Вот тот, который не работает с функцией succ
, работающей с элементами Enum
:
main :: IO ()
main = let s = succ in putStrLn $ showList [
show $ s 41,
show $ s False
] ""
Замена s = succ
на s x = succ x
все еще исправляет проблему.
У меня нетудалось найти объяснение этому неожиданному поведению.Это ошибка?Если это не так, пожалуйста, объясните, что происходит.