gpt4 book ai didi

haskell - 限制效果,例如 `Freer` ,使用 MTL 样式

转载 作者:行者123 更新时间:2023-12-02 00:38:13 25 4
gpt4 key购买 nike

动机:能够像我们在 Free/Freer 风格中那样控制 MTL 中的效果。

这个例子可能有点做作——想象一个有一些基本操作的程序(GHC 8.2 使用 freer-simple),

#!/usr/bin/env stack
-- stack --resolver lts-10.2 --install-ghc runghc --package freer-simple
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
import Control.Monad.Freer

data Effect next where
ReadFilename :: String -> Effect String
WriteOutput :: Show a => a -> Effect ()
Computation :: Int -> Int -> Effect Int

readFilename :: Member Effect effs => String -> Eff effs String
readFilename = send . ReadFilename

writeOutput :: (Member Effect effs, Show a) => a -> Eff effs ()
writeOutput = send . WriteOutput

computation :: Member Effect effs => Int -> Int -> Eff effs Int
computation i1 i2 = send $ Computation i1 i2

有了这个,我们可以模拟一个程序来做一些简单的操作,读取文件并输出它,进行计算并输出它,

program :: Eff '[Effect, IO] ()
program = do
contents <- readFilename "test.txt"
writeOutput contents
result <- computation 12 22
writeOutput result

然后我们可以实现我们的解释器,这将由我们决定如何运行代码。我们的第一个解释器将放在客户端,并在本地运行 IO 指令,并将纯指令发送到服务器进行计算,

runClientEffect :: Eff '[Effect, IO] a -> IO a
runClientEffect = runM . interpretM (\case
ReadFilename filename -> readFile filename
WriteOutput s -> print s
Computation i1 i2 -> do
print "Imagine the networking happening here"
pure $ i1 + i2)

我们现在可以跳过服务器端。

这有希望展示的是一个接口(interface),它依赖于某些方面是纯粹的,因此能够发送到服务器,而其他方面是不纯粹的,并在本地运行。

我纠结的是如何以 MTL 风格做到这一点,即如何限制可以在 monad 操作中完成的 IO 的数量。

如果问题太模糊,请告诉我!

最佳答案

这很简单。

import Control.Monad.IO.Class

我们定义了一个抽象 monad 本身的 EffectMonad 类型类,而不是代表我们 DSL 语法的 Effect 数据类型。

class Monad m => EffectMonad m where
readFilename :: String -> m String
writeOutput :: Show a => a -> m ()
computation :: Int -> Int -> m Int

程序是相同的(直到类型签名)。

program :: EffectMonad m => m ()
program = do
contents <- readFilename "test.txt"
writeOutput contents
result <- computation 12 22
writeOutput result

解释器作为实例给出(如果您使用转换器对效果进行分层,这就是我们遇到 O(n*m) 实例问题的地方)。

instance EffectMonad IO where
readFilename filename = readFile filename
writeOutput s = print s
computation i1 i2 = do
print "Imagine the networking happening here"
pure $ i1 + i2

然后运行程序只是用正确的类型实例化它。

main :: IO ()
main = program

关于haskell - 限制效果,例如 `Freer` ,使用 MTL 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48392810/

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