如何直接通过其类型构造函数在 Purescript 中创建 Effect?

How do you create an Effect in Purescript directly via its type constructor?

是否可以直接使用Effect构造函数?例如foo = Effect "howdy!"

看来这样应该是可以的。它似乎是一个类型构造函数。

:kind Effect
Type -> Type 

但是,如果我尝试构造它,则会抛出错误

Effect 1234
Unknown data constructor Effect

我只能创建一个 'indirectly' 和 pure

myeffect :: Effect Int 
myeffect = pure 123

我错过了什么吗?

这不是类型的工作方式

签名 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 构造函数的名称 - 这是一个可以构造(因此得名)值的函数类型。 构造函数的其他示例是JustNothing——它们都用于构造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魔法。类型 Effect Int 的值肯定是 NOT 一种 "box" ,其中包含 Int 。 No-no-no.

相反,类型 Effect Int 的值是一个 程序 ,它在执行时最终会产生一个 Int。你不能看里面,你不能把它拆开,你唯一能做的就是执行它。

你是如何执行的?简单!你 return 它来自你的 main 函数!

不,说真的,这是执行 Effect 的唯一方法。 (嗯,好吧,还有 unsafePerformEffect,然后你可以用 FFI 来做,但那些是入门的 hack,不要去那里)

您执行效果的正常方式是 return 如果来自您的 main 函数,运行时将处理它。轰!

另一种看待它的方式是你的整个程序很大(或很小)Effect。那是你的程序。

你可以用效果做的另一件事是使用运算符>>=(或其邪恶的双胞胎=<<)将它与另一个效果结合起来。例如:

x = pure 40
y = x >>= \a -> a + 2

z = pure 42

这里,yz 是等效的程序:两者在执行时都会产生数字 42.

这就是您在 PureScript 中编写程序的方式:您从 built-in ("magic") 产生效果的函数开始,例如 cwdreadLine 或不管怎样,然后通过 >>==<<do 符号(这是 >>= 的语法糖)将这些效果与其他效果组合在一起。然后,由许多小效果构成的大效果,您从 main 函数 return - 瞧,您得到了一个程序!