Haskell Language
Модули
Поиск…
Синтаксис
module Name где - экспортировать все имена, объявленные в этом файле
module name (functionOne, Type (..)) где - экспортировать только функции One, Type и Type
import Module - импортировать все экспортированные имена модуля
импортировать квалифицированный модуль как MN - квалифицированный импорт
import module (justThisFunction) - импортировать только определенные имена из модуля
import Module hiding (functionName, Type) - импортировать все имена из модуля, кроме функцииName и Type
замечания
Haskell поддерживает модули:
модуль может экспортировать все или подмножество его типов и функций
модуль может «реэкспортировать» имена, импортированные из других модулей
На потребительском конце модуля можно:
импортировать все или подмножество членов модуля
скрыть импорт определенного члена или набора членов
У haskell.org есть отличная глава по определению модуля.
Определение собственного модуля
Если у нас есть файл под названием Business.hs
, мы можем определить Business
модуль, который можно import
, например:
module Business (
Person (..), -- ^ Export the Person type and all its constructors and field names
employees -- ^ Export the employees function
) where
-- begin types, function definitions, etc
Возможно, более глубокая иерархия; см. пример Иерархический список модулей .
Экспорт конструкторов
Чтобы экспортировать тип и все его конструкторы, необходимо использовать следующий синтаксис:
module X (Person (..)) where
Итак, для следующих определений верхнего уровня в файле People.hs
:
data Person = Friend String | Foe deriving (Show, Eq, Ord)
isFoe Foe = True
isFoe _ = False
Это объявление модуля вверху:
module People (Person (..)) where
будет экспортировать только Person
и его конструкторов Friend
and Foe
.
Если список экспорта, следующий за ключевым словом модуля, опущен, все имена, привязанные к верхнему уровню модуля, будут экспортированы:
module People where
будет экспортировать Person
, его конструкторы и функцию isFoe
.
Импорт отдельных членов модуля
Haskell поддерживает импорт подмножества элементов из модуля.
import qualified Data.Stream (map) as D
будет импортировать map
только из Data.Stream
, и для вызова этой функции потребуется D.
.:
D.map odd [1..]
иначе компилятор попытается использовать функцию map
Prelude
.
Скрыть импорт
Prelude часто определяет функции, имена которых используются в другом месте. Не скрывая такого импорта (или используя квалифицированный импорт там, где происходят столкновения) вызовет ошибки компиляции.
Data.Stream
определяет функции с именем map
, head
и tail
которые обычно сталкиваются с теми, которые определены в Prelude. Мы можем скрыть импорт из Prelude, используя hiding
:
import Data.Stream -- everything from Data.Stream
import Prelude hiding (map, head, tail, scan, foldl, foldr, filter, dropWhile, take) -- etc
На самом деле для этого потребуется слишком много кода, чтобы скрыть конфликты Prelude, подобные этому, поэтому вместо этого вы бы использовали qualified
импорт Data.Stream
.
Квалификационный импорт
Когда несколько модулей определяют одни и те же функции по имени, компилятор будет жаловаться. В таких случаях (или для повышения удобочитаемости) мы можем использовать qualified
импорт:
import qualified Data.Stream as D
Теперь мы можем предотвратить ошибки компилятора неоднозначности, когда мы используем map
, которая определена в Prelude
и Data.Stream
:
map (== 1) [1,2,3] -- will use Prelude.map
D.map (odd) (fromList [1..]) -- will use Data.Stream.map
Также возможно импортировать модуль с только идентифицирующими именами, которые можно получить с помощью import Data.Text as T
, что позволяет иметь Text
вместо T.Text
и т. Д.
Иерархические имена модулей
Имена модулей соответствуют иерархической структуре файловой системы. Со следующим макетом файла:
Foo/
├── Baz/
│ └── Quux.hs
└── Bar.hs
Foo.hs
Bar.hs
заголовки модулей будут выглядеть так:
-- file Foo.hs
module Foo where
-- file Bar.hs
module Bar where
-- file Foo/Bar.hs
module Foo.Bar where
-- file Foo/Baz/Quux.hs
module Foo.Baz.Quux where
Обратите внимание, что:
- имя модуля основано на пути файла, объявляющего модуль
- Папки могут совместно использовать имя с модулем, который дает иерархическую структуру именования модулей