командой ghci, переключиться на директорию командой :cd и загрузить модуль командой :l Empty.
$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/
:? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :cd ~/haskell-notes/code/ch-2/
Prelude> :l Empty.hs
[1 of 1] Compiling Empty
( Empty.hs, interpreted )
Ok, modules loaded: Empty.
*Empty>
Слева от знака приглашения к вводу > отображаются загруженные в интерпретатор модули. По умол-
чанию загружается модуль Prelude. После выполнения команды :l мы видим, что Prelude сменилось на
Empty.
Теперь давайте потренируемся перезагружать модули. Давайте изменим наш модуль, сделаем его не та-
ким пустым, убрав последние две скобки от модуля Prelude в директиве import. Теперь сохраним изменения
и выполним команду :r.
*Empty> :r
[1 of 1] Compiling Empty
( Empty. hs, interpreted )
Ok, modules loaded: Empty.
*Empty>
Завершим сессию интерпретатора командой :q.
*Empty> :q
Leaving GHCi.
Внешние модули должны находится в текущей директории. Давайте потренируемся с подключением
определений из внешних модулей. Создадим модуль близнец модуля Empty. hs:
module EmptyEmpty where
import Prelude()
И сохраним его в той же директории, что и модуль Empty, теперь мы можем включить все определения
из модуля EmptyEmpty:
module Empty where
import EmptyEmpty
Когда у нас будет много модулей мы можем разместить их по директориям. Создадим в одной дирек-
тории с модулем Empty директорию Sub, а в неё поместим копию модуля Empty. Существует одна тонкость:
поскольку модуль находится в поддиректории, для того чтобы он стал виден из текущей директории, необ-
ходимо дописать через точку имя директории в которой он находится:
module Sub.Empty where
Теперь мы можем загрузить этот модуль из исходного:
module Empty where
import EmptyEmpty
import Sub.Empty
Обратите внимание на то, что мы приписываем к модулю в поддиректории Sub имя поддиректории. Если
бы он был заложен в ещё одной директории, то мы написали бы через точку имя и этой поддиректории:
module Empty where
import Sub1.Sub2.Sub3.Sub4.Empty
26 | Глава 2: Первая программа
2.3 Логические значения
Пустой модуль это хорошо, но слишком скучно. Давайте перепишем объявленные в этой главе опреде-
ления в модуль, загрузим его в интерпретатор и понабираем значения.
Начнём с логических операций. Давайте не будем переопределять Bool, Show и Eq, а просто возьмём их
из Prelude:
module Logic where
import Prelude(Bool(.. ), Show(.. ), Eq(.. ))
Две точки в скобках означают “все конструкторы” (в случае типа) и “все методы” (в случае класса типа).
Строчку
import Prelude(Bool(.. ), Show(.. ), Eq(.. ))
Следует читать так: Импортируй из модуля Prelude тип Bool и все его конструкторы и классы Show и
Eq со всеми их методами. Если бы мы захотели импортировать только конструктор True, мы бы написали
Bool(True), а если бы мы захотели импортировать лишь имя типа, мы бы написали просто Bool без скобок.
Сначала выпишем в модуль наши синонимы:
module Logic where
import Prelude(Bool(.. ), Show(.. ), Eq(.. ))
true :: Bool
true = True
false :: Bool
false = False
not :: Bool -> Bool
not True
= False
not False = True
and :: Bool -> Bool -> Bool
and False
_
= False
and True
x
= x
or
:: Bool -> Bool -> Bool
or True
_ = True
or False
x = x
xor :: Bool -> Bool -> Bool
xor a b = or (and (not a) b) (and a (not b))
ifThenElse :: Bool -> a -> a -> a
ifThenElse True
t
_ = t
ifThenElse False
_
e = e
Теперь сохраним модуль и загрузим его в интерпретатор. Для наглядности мы установим флаг +t, при
этом будет возвращено не только значение, но и его тип. Понабираем разные комбинации значений:
*Logic> :l Logic
[1 of 1] Compiling Logic
( Logic. hs, interpreted )
Ok, modules loaded: Logic.