Как вы создаете эффект в Purescript напрямую через его конструктор типов? - PullRequest
0 голосов
/ 07 июня 2019

Можно ли использовать конструктор Effect напрямую? например foo = Effect "howdy!"

Это кажется , как это должно быть возможно. Похоже, это конструктор типа.

:kind Effect
Type -> Type 

Тем не менее, если я пытаюсь построить его, выдается ошибка

Effect 1234
Unknown data constructor Effect

Я могу создать только одно "косвенно" с помощью pure

myeffect :: Effect Int 
myeffect = pure 123

Я что-то упустил?

1 Ответ

3 голосов
/ 10 июня 2019

Это не так, как работают типы

Подпись 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 - и вуаля, вы получаете программу!

...