gpt4 book ai didi

haskell - 使用来自 REPL 的 Monadic eDSL

转载 作者:行者123 更新时间:2023-12-04 17:43:56 24 4
gpt4 key购买 nike

假设我使用 monad 在 Haskell 中为自己创建了一种嵌入式领域特定语言。例如,一种允许您在堆栈上推送和弹出值的简单语言,使用状态 monad 实现:

type DSL a = State [Int] a

push :: Int -> DSL ()
pop :: DSL Int

现在我可以使用 do 表示法编写小型堆栈操作程序:
program = do
push 10
push 20
a <- pop
push (5*a)
return a

但是,我真的很想从 REPL 交互式地使用我的 DSL(特别是 GHCi,如果有帮助,我愿意使用其他的)。

不幸的是有一个像这样的 session :
>push 10
>pop
10
>push 100

不会立即起作用,这可能是相当合理的。但是,我真的认为能够做一些具有类似感觉的事情会很酷。状态 monad 的工作方式并不容易做到这一点。您需要建立您的 DSL a键入然后对其进行评估。

有没有办法做这样的事情。在 REPL 中增量使用 monad?

我一直在看诸如 operational 之类的东西, MonadPrompt , 和 MonadCont我有点感觉也许可以用来做这样的事情。不幸的是,我所见过的例子都没有解决这个特殊问题。

最佳答案

另一种可能性是每次做任何事情时都重新模拟整个历史。这适用于任何纯 monad。这是一个临时库:

{-# LANGUAGE RankNTypes #-}

import Data.IORef
import Data.Proxy

newtype REPL m f = REPL { run :: forall a. m a -> IO (f a) }

newREPL :: (Monad m) => Proxy m -> (forall a. m a -> f a) -> IO (REPL m f)
newREPL _ runM = do
accum <- newIORef (return ())
return $ REPL (\nextAction -> do
actions <- readIORef accum
writeIORef accum (actions >> nextAction >> return ())
return (runM (actions >> nextAction)))

基本上,它将迄今为止运行的所有操作存储在 IORef 中。 , 每次你做某事时,它都会添加到操作列表中并从顶部运行它。

要创建副本,请使用 newREPL ,传递给它 Proxy对于 monad 和一个“运行”函数,可以让你摆脱 monad。运行函数类型为 m a -> f a 的原因而不是 m a -> a这样您就可以在输出中包含额外的信息——例如,您可能还想查看当前状态,在这种情况下,您可以使用 f喜欢:
data StateOutput a = StateOutput a [Int]
deriving (Show)

但我刚刚用它与 Identity 一起使用没有什么特别的。
Proxy参数是这样当我们创建一个新的 repl 实例时 ghci 的默认设置不会咬我们。

以下是您如何使用它:
>>> repl <- newREPL (Proxy :: Proxy DSL) (\m -> Identity (evalState m []))
>>> run repl $ push 1
Identity ()
>>> run repl $ push 2
Identity ()
>>> run repl $ pop
Identity 2
>>> run repl $ pop
Identity 1

如果多余 Identity线路噪声困扰您,您可以使用自己的仿函数:
newtype LineOutput a = LineOutput a
instance (Show a) => Show (LineOutput a) where
show (LineOutput x) = show x

我必须做出一个小小的改变——我必须改变
type DSL a = State [Int] a


type DSL = State [Int]

因为你不能使用没有完全应用的类型同义词,就像我说的 Proxy :: DSL .无论如何,我认为后者更惯用。

关于haskell - 使用来自 REPL 的 Monadic eDSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43790376/

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