При попытке компиляции следующего кода с GHC 7.10.3, он бросает «Перекрытие Инстансы» ошибка у меня:Неясная почему экземпляры перекрывающихся
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
module Main where
class Bar a where
bar :: Foo a
-- Instance #1
instance Bar '[a] where
bar = C1
-- Instance #2
instance (Bar as) => Bar (a ': as) where
bar = C2 bar
data Foo :: [*] -> * where
C1 :: Foo '[a]
C2 :: Foo as -> Foo (a ': as)
main :: IO()
main = undefined
foobar :: Foo '[Int]
foobar = bar
28 col 10 error: Overlapping instances for Bar '[Int] arising from a use of ‘bar’
Matching instances:
instance Bar '[a] -- Defined at test.hs:13:10
instance Bar as => Bar (a : as) -- Defined at test.hs:17:10
In the expression: bar
In an equation for ‘foobar’: foobar = bar
Очевидно '[Int]
является экземпляром Bar
через #1
. Теперь я удивлен, потому что (из моего понимания ситутации) '[Int] = (Int ': '[])
не может быть экземпляром Bar
через #2
, так как '[]
сам по себе не является экземпляром Bar
(что необходимо). У меня смутные воспоминания об ограничениях на instanciation, которые не были такими, как я думал, и я подозреваю, что проблема здесь в ... (Bar as) => ...
, хотя я не могу быть уверен. Любая помощь оценивается.
Любой 'Bar (a ': as)' также будет 'Bar' [a]', no? – user2297560
@ user2297560 Нет, анализ в вопросе верен в этом вопросе: только когда 'as ~ []' '' a ': as' и '' [a]' то же самое. –
@ Даниэль Вагнер А, я вижу. Благодарю. Этот тип типа уровня все еще немного волшебный для меня. – user2297560