haskell - 如何为状态类型不透明的有状态组件创建接口(interface)?

标签 haskell interface state

-- InternalComponent.hs
data ComponentState = ComponentState ...
instance Default ComponentState where ...

componentFunction :: (MonadState InternalComponentState m) => a -> m a

-- Program.hs
data ProgramState = forall cs. ProgramState {
    componentState :: cs,
    ...
}

newtype MyMonad a = MyMonad { runMyMonad :: StateT ProgramState IO a }

myFunction a = do
    s <- get
    let cs = componentState s
    let (r, cs') = runState (componentFunction a) cs
    put $ s { componentState = cs' }
    return r

我想要的是能够使用 MyMonad 内部的 componentFunction (在 myFunction 中,如示例中所示),而无需对组件所需的实际状态类型特别感兴趣。将组件状态保留在我自己的状态中并不是必需的,但这就是我在 Haskell 中使用状态的能力。

这实际上可以被视为另一种编程语言中的有状态接口(interface)的实现的等价物:具有某些实现的接口(interface)的实例化提供默认状态值,并且通过该接口(interface)调用的每个函数都可以修改该状态。在任何时候都不会向用户提供实现细节。

如果不清楚,上面的示例失败,因为 myFunction 的实现无法证明记录选择器提供了适当的类型(因为它是存在的);至少我是这么理解的。

最佳答案

您可以通过组件状态的类型来参数化ProgramState,例如有

data ProgramState cs = ProgramState { componentState :: cs }

这意味着您还必须从 InternalComponent.hs 公开 ComponentState 类型,但不是构造函数。通过这种方式,您可以为类型检查器提供一些可以使用的东西,但不会向 InternalComponent 的用户公开任何内部结构。

关于haskell - 如何为状态类型不透明的有状态组件创建接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29333788/

相关文章:

haskell - 签名中的绑定(bind)类型

java - 为什么在调用以接口(interface)作为构造函数参数的类时出现 'source not found' 错误?

iphone - 关于iPhone应用程序状态的另一个问题

haskell - 如何规避 GHC 阶段限制?

haskell - 函数长度 "a"不编译,如果启用了 OverloadedStrings 扩展

haskell - 如何安全地分解单一的 mkYesod block

java - 实例化另一个抽象类的内部抽象类

java - Validate接口(interface)的继承设计

c - 三态 boolean

html - 具有快速鼠标悬停/鼠标移出的完整悬停动画持续时间?