3

LYAH 的 y-taka-23 改编中,我发现第 13 章的大部分片段必须处理缺少State构造函数的问题,例如原始的 Haskell 代码:

randomSt = State random 

改写为:

randomSt = do
    gen <- State.get
    let (x, newGen) = random gen
    State.put newGen
    return x 

这当然有它自己的教学优点!但我想知道是否有另一种创建State. 我知道 Frege 和 Haskell 之间的这种差异来自这样一个事实,即State s a在 Frege 的Control.monad.State模块中是一种抽象数据类型。是否可以定义派生自它的新具体数据类型并改用其构造函数?

4

2 回答 2

3

你不能只写一个智能构造函数吗?

state :: (s -> (a, s)) -> State s a
state f = do
    s <- State.get
    let (x, s') = f s
    State.put s'
    return x

编写一次(也许在您可以下载的库中?),然后在您需要的任何地方使用它。

于 2016-02-10T18:30:13.250 回答
1

事实上,一些特定的状态实例的构造

State random

非常优雅,在弗雷格中是不可能的,因为State数据构造函数不可访问。这很不幸,但它也可以防止您编写依赖于某些实现细节的代码。

例如,我正在为 Frege 开发一个新的后端,它利用 Java lambdas 并尝试发出类型安全的通用 Java 代码,在此过程中,我发现我需要另一种状态表示。因此,在下一个 Frege 版本中,State不再有将函数作为参数的构造函数。

尽管发生了这种变化,而且编译器的大部分由状态操作组成,但我不必因此而更改编译器代码中的任何一行。而且我可以肯定我不会伤害任何人的代码。大胜!

无论如何,我觉得我们可以在标准库中包含@jcast 的智能状态构造函数。(我只是将 let 重写为一个案例。)

于 2016-02-10T20:27:46.263 回答