В Нежное введение в Haskell, версия 98 это говорят:
Instance declarations are not explicitly named in import or export lists. Every module exports all of its instance declarations and every import brings all instance declarations into scope.
Мне это кажется разумным. Во всяком случае, когда я пробую это для fromNumber из экземпляра FromNumber PixelFormat Word32
, я сталкиваюсь с ошибкой:
/home/brandon/workspace/hico/src/Hico/Game.hs:269:50: error:
Variable not in scope:
fromNumber :: Word32 -> SDL.Video.Renderer.PixelFormat
|
269 | let pixFmt :: SDL.Video.Renderer.PixelFormat = fromNumber rawPixFmt
|
Тип сообщения об ошибке мне кажется правильным. Мой релевантный импорт:
import qualified SDL as SDL
import qualified SDL.Font
import qualified SDL.Image
import qualified SDL.Internal.Types (Window(..))
import qualified SDL.Raw
import SDL.Raw.Video (getWindowPixelFormat)
import qualified SDL.Video.Renderer
(особенно последняя строчка с import qualified SDL.Video.Renderer
).
Из-за чувства паранойи и поскольку у меня уже была под рукой локальная копия sdl2, я изменил код в SDL2 Renderer.hs
и добавил следующие изменения, которые успешно скомпилированы, но показывают, что проблема не в этом:
{-# LANGUAGE InstanceSigs #-}
-- omitted ...
fromNumber :: Word32 -> PixelFormat
fromNumber n' = case n' of -- ommited ...
Такое ощущение, что я снова делаю какую-то глупость с импортом, хотя не уверен.
АаааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааВа оyчке, я пытался добавить квалификаторы по-другому, но это не имело смысла .... это имеет больше смысла, и это работает! Теперь мне нужно будет протестировать проблему времени выполнения, которая возникла у меня позже, но это отвечает на мой вопрос!
@Bakuriu не возражаете, чтобы ваш комментарий стал ответом?
@luqui Я думаю, что ответ Дэниела предоставляет всю информацию. @bbarker Очевидно, что импортирование пакета с Internal
в его имени делать не следует. Но я считаю, что какой-то другой модуль публично реэкспортирует FromNumber
, так что вам придется его поискать.
Экземпляры глобальны, а сам класс и его методы - нет. Итак, если у вас есть
module X () where
instance Foo Bar where fooBar = undefined
и импортировать X
, тогда вы сможете передавать Bar
в функции, которые требуют, чтобы их аргументы были экземпляром Foo
(или получить Bar
обратно из вещей, которые обещают создать экземпляр Foo
), но не сможете назвать Foo
, Bar
, или fooBar
самостоятельно, если вы не импортировали их откуда-то еще!
Исправление в вашем случае - найти модуль, который экспортирует fromNumber
, например. экспортируя FromNumber(..)
, и импортируйте его оттуда.
Экспорт экземпляров не подразумевает экспорт определений функций или методов класса. На самом деле в сообщении об ошибке говорится, что переменная не входит в область действия (т.е. вы не импортировали
fromNumber
как функцию), а не о том, что она не может найти экземпляр. Что произойдет, если у васimport SDL.Internal.Numbered
(который, я считаю, является модулем, определяющимfromNumber
)?