Я играл с очень простой программой haskell и забыл цитату в вызове функции (последний lookup
вызывается в следующем примере кода).GHC Толкование сообщений об ошибках
import Data.List
main :: IO()
main = do
let sum = sumAllOddSquaresSmallerThan 100
print sum
let testMap = [(4,"Foo"), (2,"Bar"), (1,"Baz")]
print $ lookup' testMap 2
sumAllOddSquaresSmallerThan :: (Ord a, Integral a) => a -> a
sumAllOddSquaresSmallerThan n = sum(takeWhile (<n) (filter odd (map (^2) [1..])))
lookup' :: Eq a => [(a,b)] -> a -> b
lookup' [] _ = error("key not in the list")
lookup' ((x',y'):xs) x = if x' == x then y' else lookup xs x
Сообщение об ошибке дается GHC является следующий:
CompilerErrorTest.hs:12:70:
Could not deduce (Integral b1) arising from a use of ‘^’
from the context (Ord a, Integral a)
bound by the type signature for
sumAllOddSquaresSmallerThan :: (Ord a, Integral a) => a -> a
at CompilerErrorTest.hs:11:32-60
The type variable ‘b1’ is ambiguous
Note: there are several potential instances:
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral GHC.Types.Word -- Defined in ‘GHC.Real’
In the first argument of ‘map’, namely ‘(^ 2)’
In the second argument of ‘filter’, namely ‘(map (^ 2) [1 .. ])’
In the second argument of ‘takeWhile’, namely
‘(filter odd (map (^ 2) [1 .. ]))’
CompilerErrorTest.hs:12:71:
Could not deduce (Num b1) arising from the literal ‘2’
from the context (Ord a, Integral a)
bound by the type signature for
sumAllOddSquaresSmallerThan :: (Ord a, Integral a) => a -> a
at CompilerErrorTest.hs:11:32-60
The type variable ‘b1’ is ambiguous
Note: there are several potential instances:
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus three others
In the second argument of ‘(^)’, namely ‘2’
In the first argument of ‘map’, namely ‘(^ 2)’
In the second argument of ‘filter’, namely ‘(map (^ 2) [1 .. ])’
CompilerErrorTest.hs:17:60:
Could not deduce (a ~ [([(a, b)], b0)])
from the context (Eq a)
bound by the type signature for
lookup' :: Eq a => [(a, b)] -> a -> b
at CompilerErrorTest.hs:15:12-36
‘a’ is a rigid type variable bound by
the type signature for lookup' :: Eq a => [(a, b)] -> a -> b
at CompilerErrorTest.hs:15:12
Relevant bindings include
x :: a (bound at CompilerErrorTest.hs:17:22)
xs :: [(a, b)] (bound at CompilerErrorTest.hs:17:18)
y' :: b (bound at CompilerErrorTest.hs:17:14)
x' :: a (bound at CompilerErrorTest.hs:17:11)
lookup' :: [(a, b)] -> a -> b (bound at CompilerErrorTest.hs:16:1)
In the second argument of ‘lookup’, namely ‘x’
In the expression: lookup xs x
Чтобы сделать вопрос еще хуже, я впервые попробовал пример в FP Полный онлайн Haskell IDE, который скрывался последние две строки сообщение об ошибке (я не заметил ... ближе к концу сообщения)
Может кто-нибудь объяснить, почему GHC дает эти ошибки в несвязанной функции sumAllOddSquaresSmallerThan
и как я мог сузить источник ошибки быстро?
Способ, которым я отлаживал это, заключается в том, что я бы прокомментировал все функции и попробовал не комментировать каждую функцию. Это покажет, что ваша функция 'lookup'' имеет проблему. А потом оттуда легче отлаживать. При этом haskell поддерживает хорошее интерактивное развитие. Итак, как вы, когда вы пишете одну функцию, вы можете загрузить их в ghci и убедиться, что для себя, если она работает или нет. Вы не хотите писать 1000 строк кода, а затем попытаться скомпилировать его. :) – Sibi
Я не думаю, что это ожидаемое поведение для GHC (это может быть ошибка?) - поскольку они действительно не связаны вообще, но я уверен, что кто-то докажет мне, что я ошибаюсь, и я не видел некоторых простое объяснение;) – Carsten
Это выглядит как регрессия GHC, ИМХО. Код выше в ghc-7.6.3 дает только две ошибки вокруг строки 'lookup', которая выглядит нормально. Вместо этого ghc-7.8.3 генерирует несвязанные ошибки, показанные выше. Интересно, делает ли ghc-7.10.1 то же самое. – chi