是否有约定,以便我知道何时需要runX
与getX
类型类函数?
答案 0 :(得分:4)
这完全取决于作者如何选择考虑他们所代表的内容。它通常更多地是关于被表示的“抽象概念”,而不是用于表示它的实际数据结构。
如果您有某种类型X
并将X
值视为可以运行以获取值的计算,那么您将拥有runX
1}}功能。如果您认为它更像是容器,那么您将拥有getX
函数(还有其他可能的解释可能导致runX
或{{1}或者别的什么,这些只是两种常见的思考价值观的方式。)
当然,当我们使用第一类Haskell值来表示事物(并且函数是非常好的值)时,很多时候你可以将某些东西理解为计算或容器。考虑getX
表示有状态计算; 肯定必须被解释为计算,对吧?我们说State
是因为我们将其视为“正在运行”runState :: State s a -> s -> (a , s)
,需要State s a
作为附加输入。但我们可以很容易地将其视为s
中的s -> (a, s)
- 将State s a
视为容器。
所以State
和runX
之间的选择在任何深刻的时态都没有真正的意义,但它告诉你作者是如何思考getX
的(也许他们是怎么想你的应该考虑一下。)
X
的命名类似于函数Const
(它接受一个参数来产生“常量函数”,它接受另一个输入,忽略它,并返回任何第一个输入到{ {1}}是。但它被认为是在类型级别运行; const
采用类型并生成“类型级函数”,忽略它应用的任何类型,然后与应用的第一个类型const
同构。同构而不是相等,因为要创建一个可能具有不同实例的新类型,它需要有一个构造函数。在值级别,为了成为同构,您需要能够从Const
(即Const
构造函数)获取Const a b
,并且从a
中取出Const
。由于“与a
同构”是所有我们需要的属性,除了作为Const a b
的简单容器之外,没有必要将其视为做任何其他事情。 ,所以我们有a
。
a
似乎同样显而易见,只是“只是一个容器”,我们有getConst
。但Identity
的主要动机之一是将runIdentity
视为“monadic计算”,其方式与Identity
,Identity a
等值相同。因此,为了继续类比,我们将State s a
视为“无所事事”计算我们运行,而不是我们从中获取值的简单包装容器。将<{1}}视为容器(最简单的容器) 是完全有效的,但这不是作者选择关注的解释。