You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为被runST执行,ST的状态是否需保持不变?

关于Haskell中runST与参数性的探讨

先看这段ST和runST的定义(存在不少错误,但runST的核心结构如下):

type ST s a = ST (s -> (s, a))

runST :: (forall s. ST s a) -> a
runST (ST f) = case (f realWorld) of (_, a) -> a

要将runST应用于类型为ST s a(等价于s -> (s, a))的值,类型s必须是完全参数化的。

无法被runST应用的函数示例

部分依赖具体类型的函数无法通过runST执行,比如:

\s -> (s + s, "hello world")   -- 无法运行,依赖Num类型类

fun [] = ([], 0)
fun (x : xs) = (xs, length (x : xs))  -- 无法运行,依赖[]类型

可被runST执行的函数形式

符合要求的函数结构应该如下:

\s -> (s, fun s)

fun = maybe some native code, not haskell.

关键在于,s -> (s, a)中返回的s必须和输入的s完全一致,类似恒等操作,这就是参数性(parametricity)。

关于RealWorld与State#的猜想

我了解到,如果s包含RealWorld,哪怕看似是恒等操作,也能完成有意义的计算(尽管这不属于纯Haskell范畴)。

为验证这个猜想,我设计了一个实验:

//given
newMutVar# :: v -> State# s -> (# State# s, MutVar# s v #)

//then (this is pseudo code)
let (# s#, var# #) = newMutVar# "hello world" (State# 0) in
    s# == State# 0

我想确认结果是否为True——若是,就说明newMutVar#对State#的作用类似恒等操作。

但我没法完成这个实验,原因有两点:

  • 我不知道如何生成State# s类型的值,仅了解对应RealWorld的值生成方式,但这没有意义,因为RealWorld内部只有一个值,无论映射逻辑如何它都不会改变。
  • 即便能生成State# 0,也无法和s#比较,因为State# s并未实现Eq类型类。

内容的提问来源于stack exchange,提问作者kwonryul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:40:09