У меня есть следующая строка кода, в которой я пытаюсь извлечь внутренний необработанный тип, чтобы я мог работать с ним напрямую:
SDL.Internal.Types.Window (rawWindow) = window
Мой импорт выглядит так:
import qualified SDL.Internal.Types (Window)
Ошибка, которую я получаю, приведена ниже; кажется, я уже делаю то, что он предлагает.
% /home/brandon/workspace/hico/src/Hico/Game.hs:273:5: error:
Not in scope: data constructor `SDL.Internal.Types.Window'
Perhaps you want to add `Window' to the import list
in the import of `SDL.Internal.Types' (src/Hico/Game.hs:34:1-48).
|
273 | SDL.Internal.Types.Window (rawWindow) = window
| ^^^^^^^^^^^^^^^^^^^^^^^^^
Содержимое файла Types.hs
очень короткое и, похоже, не дает мне никаких подсказок:
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneriC#-}
module SDL.Internal.Types
( Joystick(..)
, Window(..)
, Renderer(..)
) where
import Data.Data (Data)
import Data.Typeable
import GHC.Generics (Generic)
import qualified SDL.Raw as Raw
newtype Joystick = Joystick { joystickPtr :: Raw.Joystick }
deriving (Data, Eq, Generic, Ord, Show, Typeable)
newtype Window = Window (Raw.Window)
deriving (Data, Eq, Generic, Ord, Show, Typeable)
-- | An SDL rendering device. This can be created with 'SDL.Video.createRenderer'.
newtype Renderer = Renderer Raw.Renderer
deriving (Data, Eq, Generic, Ord, Show, Typeable)
Написав
import qualified SDL.Internal.Types (Window)
вы импортируете только тип Window и ни один из его конструкторов. Чтобы импортировать тип данных и некоторое ограниченное подмножество его конструкторов, нужно записать (используя в качестве примера Maybe, потому что я не знаю типов SDL):
import Prelude (Maybe(Just))
Этот импорт позволит вам использовать Maybe в аннотациях типов и использовать конструктор Just для сопоставления с образцом или для создания новых значений типа Maybe a, но вы не сможете использовать Nothing ни в одном из этих обстоятельств.
Обратите внимание, что описанное выше было бы очень необычным делом: обычно вам нужны либо все конструкторы типа (чтобы вы могли создавать и использовать любое значение этого типа), либо ни один из них (чтобы ваши функции могли получать или возвращать значения этого типа, созданные и потребляемые другими функциями).
Если вам нужны все конструкторы типа, вы можете использовать точный синтаксис, используемый в указанном вами определении экспорта модуля: (..)
означает «все конструкторы этого типа»:
import qualified SDL.Internal.Types (Window(..))
@dfeuer Действительно. Я отредактировал вопрос, чтобы указать, что довольно странно импортировать подмножество конструкторов.
Я настоятельно рекомендую либо экспортировать / импортировать конструкторы все (с использованием синтаксиса
(..)
), либо их никто, за исключением очень необычных обстоятельств. Ограничение только некоторыми из них предполагает использование частичных функций, а их явное перечисление - это просто дополнительная работа заранее и при изменении типа. Единственный раз, когда я мог бы рассмотреть возможность экспорта только некоторых конструкторов, было бы, если бы другие использовались временно для внутренних целей, как в некоторых формулировках красно-черных деревьев.