0
GHC не разрешает/не распространяет ограничение в реализации по умолчанию некоторых моих членов класса. Поведение действительно странно, и мне кажется, что это ошибка.GHC не разрешает корректное ограничение в методах типов (ошибка/ограничение ghc?)
Может кто-нибудь помочь мне/объяснить мне, что случилось?
- Как я могу сказать GHC унифицировать
a
из декларации класса иa
из метода класса, так что определение не является неоднозначным - Есть ли что-то я не понимаю?
код:
module Foo where
import Data.Proxy
data Stuff a = Stuff
{content :: String}
class HasStuff a where
stuff :: Stuff a
-- This works
useStuffOK :: Proxy a -> (Stuff a)
useStuffOK _ = (stuff)
-- those don't work,
-- (but I think ghc has all the information necessary to figure it out)
useStuffBAD :: Proxy a -> (Stuff a, String)
useStuffBAD _ = (stuff, content (stuff :: Stuff a))
-- Could not deduce (HasStuff a1) arising from a use of ‘stuff’
-- from the context (HasStuff a)
-- bound by the class declaration for ‘HasStuff’
-- at Test.hs:(7,1)-(17,45)
useStuffBAD2 :: Proxy a -> String
useStuffBAD2 _ = content (stuff :: Stuff a)
-- Could not deduce (HasStuff a1) arising from a use of ‘stuff’
-- from the context (HasStuff a)
-- bound by the class declaration for ‘HasStuff’
-- at Test.hs:(7,1)-(17,45)
instance HasStuff Int where
stuff = Stuff "ok"
-- inference works here
x :: Stuff Int
x = stuff
-- works here too
x :: String
x = content (stuff :: Stuff Int)
Спасибо
Это не ошибка. 'useStuffBAD _ = let x = stuff in (x, content x)' и 'useStuffBAD2 = content. useStuffOK'. Тип там действительно неоднозначен - вы можете ссылаться на любой «материал» в любом из этих выражений. 'useStuffOK' работает, потому что тип вывода задается сигнатурой типа. Поскольку 'content :: Stuff a -> String' не упоминает тип' a' в результате, использование этой функции неоднозначно, если тип явно не указан или не может быть выведен из контекста. – user2407038
@ user2407038 только что отредактировал мой вопрос: когда я даю тип явно, он не работает ни потому, что ghc не унифицирует 'a' из объявления класса, а' a' из метода класса. В моем случае useStuffBAD явно указывает, какой экземпляр он должен выбрать. У меня все еще создается впечатление, что это проблема в ghc. – Rvion
Я думаю, вам, возможно, понадобится '{- # LANGUAGE ScopedTypeVariables # -}' поверх вашего файла для работы - сам по себе ghc не знает, что 'Stuff a' from' (Stuff a, String) 'тот же как 'stuff :: Stuff a' – epsilonhalbe