您如何直接通过PureScript的类型构造函数创建效果?

时间:2019-06-07 04:56:08

标签: purescript

是否可以直接使用public static void main(String[] args) { // Assume there's a 3 x 3 array. int[][] intArray = new int[][]{ { 100, 50, 40}, { 30, 60, 20}, { 10, 5, 0} }; // Outer loop. for (int i = 0; i < intArray.length; i++) { // Inner loop. for (int j = 0; j < intArray[i].length; j++) { // Second round of loop. // Compare this element to all the next elements. // If you want to compare this with all the elements, set int k = 0. for (int k = i; k < intArray.length; k++) { for (int l = 0; l < intArray[k].length; l++) { if (intArray[i][j] < intArray[k][l]) { // Do something. } } } } } } 构造函数?例如Effect

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

foo = Effect "howdy!"

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

:kind Effect
Type -> Type 

我只能使用Effect 1234 Unknown data constructor Effect

创建一个“间接”对象
pure

我想念什么吗?

1 个答案:

答案 0 :(得分:3)

这不是类型的工作方式

签名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的方式。 / p>

(同样,某些类型可能具有多个构造函数,例如data Maybe a = Just a | Nothing,但这已经花费了太长时间)

但所有这些甚至都不适用于Effect,因为...

这不是Effect的工作方式

Effect根本没有任何构造函数。不管参数如何,绝对没有办法直接创建这种类型的值。

这是因为Effect魔术。类型Effect Int的值肯定 NOT 是一种“框”,其中包含Int。不,不。

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

您如何执行它?简单!您可以从main函数中返回它!

不,严重的是,这是执行Effect的唯一方法。 (好吧,还有unsafePerformEffect,然后您可以使用FFI来做到这一点,但是这些都是针对初学者的,请不要去那里)

执行效果的通常方法是从main函数返回,并且运行时会照顾它。轰!

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

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

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

z = pure 42

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

这就是在PureScript中编写程序的方式:从内置的(“魔术”)函数开始,这些函数会产生效果,例如cwdreadLine等,然后合成这些通过>>==<<do表示法(这是>>=的语法糖)与他人共同作用。然后,由许多小的结果构成的结果很大的效果,您将从main函数返回-瞧,您就有了一个程序!