在 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 重写为一个案例。)
在 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 重写为一个案例。)