Это не так, как работают типы
Подпись Effect :: Type -> Type
означает, что если вы возьмете слово Effect
и прикрепите тип справа от него, результатом будет другой тип.Итак:
Effect :: Type -> Type
Int :: Type
Effect Int :: Type
Это ничего не говорит о создании значений типа Effect
.То есть:
Effect Int :: Type
x :: Effect Int
x = Effect 42 -- not necessarily allowed
Для многих типов это работает просто отлично, например:
Maybe Int :: Type
x :: Maybe Int
x = Just 42 -- perfectly valid
Но это не обязательно.Все зависит от того, как определяется тип.Например:
data MyType a = Foo
MyType :: Type -> Type
MyType Int :: Type
x = Foo 42 -- now allowed
y = Foo -- allowed
Обратите внимание, что я использую слово Foo
для построения значений MyType
, а не слова MyType
.Это потому что они разные вещи.MyType
- это имя типа, а Foo
- это имя конструктора - функции, которая может создавать (отсюда и имя) значения типа.Другими примерами конструкторов являются Just
и Nothing
- оба используются для построения значений типа Maybe
.
Конструктор может иметь то же количество параметров, что и сам тип,или он может иметь меньше параметров или больше.Например:
data Type1 a = Ctor1 a
data Type2 a = Ctor2
data Type3 a = Ctor3 a a
x :: Type1 Int
x = Ctor1 42
y :: Type2 Int
y = Ctor2
z :: Type3 Int
z = Ctor3 42 84
Итак, подведем итог: в зависимости от того, как определен тип, вы можете или не можете использовать имя типа для создания значений этого типа, как вы пытаетесьделать с Effect
.
(также некоторые типы могут иметь несколько конструкторов, например, data Maybe a = Just a | Nothing
, но это уже занимает слишком много времени)
Но всеэто даже не относится к Effect
, потому что ...
Это не то, как Effect
работает
Effect
вообще не имеет никаких конструкторов.Абсолютно невозможно напрямую создать значения этого типа независимо от параметров.
Это потому, что Effect
- это magic .Значение типа Effect Int
определенно является НЕ своего рода «коробкой», которая содержит Int
внутри.Нет-нет-нет.
Вместо этого значение типа Effect Int
представляет собой программу , которая при выполнении в конечном итоге выдаст Int
.Вы не можете заглянуть внутрь, вы не можете разобрать его, единственное, что вы можете с ним сделать - это выполнить его.
И как вы выполняете это?Легко!Вы возвращаете его из функции main
!
Нет, серьезно, это единственный способ выполнить Effect
.(хорошо, хорошо, есть также unsafePerformEffect
, и затем вы можете сделать это с FFI, но это хаки для инициированных, не ходите туда)
Обычный способ выполнения эффекта - возвратесли из вашей main
функции, и среда выполнения позаботится об этом.Бум!
Еще один способ взглянуть на это, что вся ваша программа одна большая (или маленькая) Effect
.Это ваша программа.
Еще одна вещь, которую вы можете сделать с эффектом, - это объединить его с другим эффектом, используя оператор >>=
(или его злой двойник =<<
).Например:
x = pure 40
y = x >>= \a -> a + 2
z = pure 42
Здесь y
и z
- эквивалентные программы: обе программы при выполнении будут выдавать число 42
.
.программы на PureScript: вы начинаете со встроенных («магических») функций, которые производят эффекты, такие как cwd
или readLine
или что-либо еще, а затем комбинируете эти эффекты с другими с помощью >>=
или =<<
или1096 * обозначение (что является синтаксическим сахаром для >>=
).Затем в результате большого эффекта, созданного из множества маленьких, вы возвращаетесь из своей функции main
- и вуаля, вы получаете программу!