在 Frege 中创建 State 实例

Creating instance of State in Frege

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

randomSt = State random 

重写为:

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

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

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

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

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

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

State random

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

例如,我目前正在为 Frege 开发一个新的后端,它利用 Java lambda 并尝试发出类型安全的通用 Java 代码,结果在这样做的过程中我需要 State 的另一种表示形式。因此,在 Frege 的下一个版本中,根本就没有 State 构造函数可以将函数作为参数。

尽管有此更改,而且编译器的大部分由状态操作组成,但我不必因此更改编译器代码中的任何一行。而且我也可以确定我不会伤害任何其他人的代码。大赢家!

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