Haskell 这是类型声明吗?
哈斯克尔是个新手。我在网上关注这本生成性艺术教程,发现了下面的代码片段。我运行了它,它运行得很好。问题是我一点都不懂Haskell 这是类型声明吗?,haskell,Haskell,哈斯克尔是个新手。我在网上关注这本生成性艺术教程,发现了下面的代码片段。我运行了它,它运行得很好。问题是我一点都不懂 type Generate a = RandT StdGen (ReaderT World Render) a 是产品类型声明吗?如果是,那么是否可以像上面那样在括号中组合一组类型?在我看来,它更像是一个在类型或类似类型中定义的函数。我认为不清楚如何解析它,所以让我们将其分解 type Generate a = RandT StdGen (ReaderT Wor
type Generate a = RandT StdGen (ReaderT World Render) a
是产品类型声明吗?如果是,那么是否可以像上面那样在括号中组合一组类型?在我看来,它更像是一个在类型或类似类型中定义的函数。我认为不清楚如何解析它,所以让我们将其分解
type
Generate a
=
RandT
StdGen
(ReaderT
World
Render)
a
让我们把它分解一下。第1行是type
这意味着“我在这里定义一个类型别名”。类型别名是另一个类型的简写,与扩展到的类型完全相同。请注意,data
表示“我正在定义一个新的数据类型,这就是如何构造它的值”
第2行表示“该类型将被称为Generate
,是一个has参数a
”,即Generate
是某个类型级别的函数(在这种情况下,类型例如Int
或可能Int
,而不是可能
)
第4行表示该类型等于类型构造函数的某个应用程序RandT
。这个东西有种*->(*->*)->*->*->*
,它的意思大致是:
ReaderT
的一个应用程序,一种类型级别的东西*->(*->*)->*->*->*
。第一个论点是你想读的东西(世界的状态)。第二个是你想要建立的单子。在本例中,渲染
,我假设让您边走边构建艺术。没有第三种,所以就像在普通的哈斯凯尔(Haskell)中使用咖喱一样,这种咖喱的结果是*->*
,这是RandT
想要的那种
阅读的方法是:
Generate
是一个单子,可以使用随机数生成(使用标准生成器),读取类型为World
的值,然后渲染艺术。我认为不清楚如何解析它,所以让我们将其分解
type
Generate a
=
RandT
StdGen
(ReaderT
World
Render)
a
让我们把它分解一下。第1行是type
这意味着“我在这里定义一个类型别名”。类型别名是另一个类型的简写,与扩展到的类型完全相同。请注意,data
表示“我正在定义一个新的数据类型,这就是如何构造它的值”
第2行表示“该类型将被称为Generate
,是一个has参数a
”,即Generate
是某个类型级别的函数(在这种情况下,类型例如Int
或可能Int
,而不是可能
)
第4行表示该类型等于类型构造函数的某个应用程序RandT
。这个东西有种*->(*->*)->*->*->*
,它的意思大致是:
ReaderT
的一个应用程序,一种类型级别的东西*->(*->*)->*->*->*
。第一个论点是你想读的东西(世界的状态)。第二个是你想要建立的单子。在本例中,渲染
,我假设让您边走边构建艺术。没有第三种,所以就像在普通的哈斯凯尔(Haskell)中使用咖喱一样,这种咖喱的结果是*->*
,这是RandT
想要的那种
阅读的方法是:
Generate
是一种单子,可以使用随机数生成(使用标准生成器),读取类型为World
的值,然后渲染艺术。由于到目前为止还没有人提到它,所以您要查找的术语是Monad transformer。Monad transformers允许您在现有动作类型的基础上添加各种效果。示例包括ReaderT
、StateT
和MaybeT
。因此,在您的示例中,您有:
是描述渲染操作的Render
Monad
是一个monad转换器;当应用于monad时,它会生成一个monad,该monad可以读取类型为ReaderT World
的不可变环境。因此,World
是一个描述ReaderT World Render
动作的monad,它还存储了一个Render
,可以通过World
或ask
这种类型的内部动作来读取,例如,asks
World,因为到目前为止还没有人提到过它,所以您要寻找的术语是monad transformer。Monad transformers允许您在现有动作类型的基础上添加各种效果。示例包括
、ReaderT
和StateT
。因此,在您的示例中,您有:MaybeT
是描述渲染操作的Render
Monad
是一个monad转换器;当应用于monad时,它会生成一个monad,该monad可以读取类型为ReaderT World
的不可变环境。因此,World
是一个monad,它描述了ReaderT World Render
操作,还存储了一个Render
,可以通过World
或ask
这种类型的内部操作来读取,例如,asks
World这是一个类型别名。因此,您可以编写
,但在幕后是生成一个
。它不是一个产品类型声明。这类似于RandT StdGen(ReaderT World Render)一个
datat