gpt4 book ai didi

Haskell:如何在 State monad 之上编写交互式解释器?

转载 作者:行者123 更新时间:2023-12-03 14:13:46 31 4
gpt4 key购买 nike

我们正在开发一个在内部使用状态单子(monad)的模型文件系统。我们有一个类型类,其操作如下:

class Monad m => FS m where
isDirectory :: Path -> m Bool
children :: Path -> m [Path]
...

我们正在开发一个小的交互式解释器,它将提供像 cd 这样的命令。 , ls , cat , 等等。解释器中的操作可以这样写:
fsop :: FS m => Operation -> m Response
Operation 的定义和 Response不重要;如果你喜欢,把它们当作字符串。

我要解决的问题是在解释文件系统的 I/O monad 中编写一个顶级循环 Operation s 并打印响应。如果 IO 是 FS 的一个实例(也就是说,如果我们直接使用 IO monad),生活会很简单:我们可以写
loop :: Path -> IO ()
loop currentDir = do
op <- getLine
case read op of
ChangeDir d -> loop d -- should test 'isDirectory d', but let's not
Ls -> do { files <- children currentDir
; mapM_ putStrLn files
; loop currentDir }
Exit -> return ()

但这不是我想要的。我想使用 Control.Monad.State :
newtype Filesystem a = Filesystem (State (Data.Map.Map Path Contents) a)

并声明
instance Monad Filesystem ...
instance FS Filesystem ...

使用 FS抽象,我可以编写一个适用于任何实例的单步函数,并且确实可以编译以下代码:
step :: FS fs => Path -> Operation -> fs (Path, Response)
step currentDir op =
case op of
ChangeDir d -> return (d, "")
Ls -> do { files <- children currentDir
; return (currentDir, unlines files) }

在这一点上,我完全被困住了。 我要做的是在 IO monad 中编写一个交互式循环,可以读取 Operation s 和打印 Response s,但它适用于不一定是 IO 的状态单子(monad)。 (有一个不在 IO 中的模型的原因之一是我们可以测试 QuickCheck 属性。)

我觉得这必须是一个标准问题——在不是 IO 的有状态抽象之上的交互式读取-评估-打印循环。 ——但我一定错过了一些非常明显的东西,因为我似乎无法弄清楚。我在网上看过,但没有开悟。

任何帮助编写可调用 step 的交互式、执行 IO 的计算将不胜感激。

最佳答案

使用单子(monad)变压器怎么样?它们或多或少是组合 monad 的标准方式。这是一个简单的例子:

type Foo a = StateT String IO a

replT :: Foo ()
replT = do
str <- liftIO getLine
state <- get
liftIO $ putStrLn ("current state: " ++ state)
liftIO $ putStrLn ("setting state: " ++ str)
put str
replT

下面是从 ghci 中运行 replT 的结果。
*Main> runStateT replT "Initial state"
asd
current state: Initial state
setting state: asd
zxc
current state: asd
setting state: zxc
asdasd

有三个 monad 转换器库。 mtl、变压器和 monadLib。我不能推荐它们中的任何一个,因为我不经常使用它们。

关于Haskell:如何在 State monad 之上编写交互式解释器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3206869/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com