Ответ 1
Здесь есть две вещи. Экспорт синтаксиса и различие в поведении GHCi между скомпилированными и интерпретируемыми значениями.
Синтаксис экспорта
Экспорт из модуля с использованием этого синтаксиса
module System.Random (
-- ...
, StdGen
-- ...
указывает GHC только экспортировать тип данных, а не конструктор (даже если оба имеют одинаковое имя). Конструктор может быть указан явно в круглых скобках после имени типа данных, если вы хотите экспортировать его, например:
StdGen(StdGen)
Или вы можете экспортировать тип данных со всеми его конструкторами, такими как:
StdGen(..)
поведение GHCi
Кроме того, GHCi при загрузке интерпретируемого модуля всегда позволяет видеть все объекты, видимые на верхнем уровне модуля, даже если они скрыты в списке экспорта. Это облегчает разработку и отладку, и именно поэтому ваш Foo
виден.
Этот режим, в котором отображается "все", отражается, помещая *
перед именем модуля в приглашении GHCi. Если есть *
, все будет видимым, а если нет, то экспортируемые объекты будут видны.
При использовании команды :m
для добавления или удаления модулей из области видимости вы можете выбрать, хотите ли вы добавлять модули в *
-form или нет.
Но для скомпилированных модулей (и обычно компилируется библиотечный модуль, например System.Random
) форма *
недоступна, поэтому для них вы всегда будете в ситуации, когда соблюдается список экспорта.
См. документацию для полного описания поведения области действия GHCi.