FreeT 生成的解释器 monad 转换器的 MonadFix 实例?

2024-01-07

我有一个由以下命令生成的标准解释器 monad 转换器的简化版本FreeT:

data InteractiveF p r a = Interact p (r -> a)

type Interactive p r = FreeT (InteractiveF p r)

p是“提示”,并且r是“环境”...可以使用以下命令来运行它:

runInteractive :: Monad m => (p -> m r) -> Interactive p r m a -> m a
runInteractive prompt iact = do
  ran <- runFreeT iact
  case ran of
    Pure x -> return x
    Free (Interact p f) -> do
      response <- prompt p
      runInteractive prompt (f resp)

instance MonadFix m => MonadFix (FreeT (InteractiveF p r)) m a)
mfix = -- ???

我觉得这种类型或多或少只是一个受限版本StateT...如果有的话,一个Interactive p r IO我认为是一个受限版本IO...我想...但是...好吧,无论如何,我的直觉告诉我应该有一个很好的例子。

我尝试写一个,但我似乎无法真正弄清楚。到目前为止我最接近的尝试是:

mfix f = FreeT (mfix (runFreeT . f . breakdown))
  where
    breakdown :: FreeF (InteractiveF p r) a (FreeT (InteractiveF p r) m a) -> a
    breakdown (Pure x) = x
    breakdown (Free (Interact p r)) = -- ...?

我还尝试使用一个版本,利用MonadFix的实例m,但也没有运气——

mfix f = FreeT $ do
  rec ran <- runFreeT (f z)
      z   <- case ran of
               Pure x -> return x
               Free iact -> -- ...
  return -- ...

任何人都知道这是否真的可能,或者为什么不可能?如果是的话,什么地方适合我继续寻找?


或者,在我的实际应用程序中,我什至不需要使用FreeT...我可以使用Free;也就是说,有Interactive只是一个 monad 而不仅仅是一个 monad 转换器,并且有

runInteractive :: Monad m => (p -> m r) -> Interactive p r a -> m a
runInteractive _ (Pure x) = return x
runInteractive prompt (Free (Interact p f) = do
    response <- prompt p
    runInteractive prompt (f response)

如果对于这种情况而不是一般的 FreeT 情况有可能,我也会很高兴:)


假设您已经有一名口译员Interactive.

interpret :: FreeT (InteractiveF p r) m a -> m a
interpret = undefined

写一个微不足道的MonadFix实例:

instance MonadFix m => MonadFix (FreeT (InteractiveF p r) m) where
    mfix = lift . mfix . (interpret .)

我们可以直接捕捉“了解解释器”的想法,而无需提前委托解释器。

{-# LANGUAGE RankNTypes #-}

data UnFreeT t m a = UnFree {runUnFreeT :: (forall x. t m x -> m x) -> t m a}
--   given an interpreter from `t m` to `m` ^                          |
--                                  we have a value in `t m` of type a ^

UnFreeT只是一个ReaderT读取解释器。

If t是一个 Monad 转换器,UnFreeT t也是一个 monad 转换器。我们可以轻松构建一个UnFreeT来自不需要了解解释器的计算,只需忽略解释器即可。

unfree :: t m a -> UnFreeT t m a
--unfree = UnFree . const
unfree x = UnFree $ \_ -> x

instance (MonadTrans t) => MonadTrans (UnFreeT t) where
    lift = unfree . lift

If t是一个 Monad 转换器,m is a Monad, and t m也是一个Monad, then UnFree t m is a Monad。给定一个解释器,我们可以将需要解释器的两个计算绑定在一起。

{-# LANGUAGE FlexibleContexts #-}

refree :: (forall x. t m x -> m x) -> UnFreeT t m a -> t m a
-- refree = flip runUnFreeT
refree interpreter x = runUnFreeT x interpreter

instance (MonadTrans t, Monad m, Monad (t m)) => Monad (UnFreeT t m) where
    return = lift . return
    x >>= k = UnFree $ \interpreter -> runUnFreeT x interpreter >>= refree interpreter . k

最后,给定解释器,只要底层 monad 有一个,我们就可以修复计算MonadFix实例。

instance (MonadTrans t, MonadFix m, Monad (t m)) => MonadFix (UnFreeT t m) where
    mfix f = UnFree $ \interpreter -> lift . mfix $ interpreter . refree interpreter . f

一旦我们有了解释器,我们实际上可以做底层 monad 可以做的任何事情。这是因为,一旦我们有了interpreter :: forall x. t m x -> m x我们可以做以下所有事情。我们可以从m x通过t m x一直到UnFreeT t m x然后再次下降。

                      forall x.
lift               ::           m x ->         t m x
unfree             ::         t m x -> UnFreeT t m x
refree interpreter :: UnFreeT t m x ->         t m x
interpreter        ::         t m x ->           m x

Usage

为您Interactive,你会包裹FreeT in UnFreeT.

type Interactive p r = UnFreeT (FreeT (InteractiveF p r))

你的解释器仍然会被编写来产生一个FreeT (InteractiveF p r) m a -> m a。来解读新Interactive p r m a一直到m a你会用

interpreter . refree interpreter

The UnFreeT不再“尽可能地释放口译员”。口译员不能再随心所欲地决定要做什么。中的计算UnFreeT可以请求翻译。当计算请求并使用解释器时,将使用与开始解释程序相同的解释器来解释程序的该部分。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeT 生成的解释器 monad 转换器的 MonadFix 实例? 的相关文章

  • 是否有使用严格求值的 Haskell 编译器或预处理器?

    我正在寻找一个默认使用严格求值而不是惰性求值的 Haskell 编译器 我只想使用 OCaml 但 Haskell 的语法是好多了比 OCaml 的 Haskell 是纯粹的 并且具有很酷的功能 例如类型类 我真的不想经常把 s and 我
  • Haskell / SmallCheck:如何控制“Depth”参数?

    我有一个简单的数据结构可以在smallcheck 中测试 LANGUAGE FlexibleInstances MultiParamTypeClasses LANGUAGE DeriveGeneric import Test Tasty i
  • 你在实际项目中使用过Quickcheck吗[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 快速检查 http www cs chalmers se rjmh QuickCheck 及其变体 即使有一个Java https bitbuc
  • 理解 Haskell 中的矩阵转置函数

    这个矩阵转置函数有效 但我试图理解它的逐步执行 但我不明白 transpose a gt a transpose transpose x map head x transpose map tail x with transpose 1 2
  • 是否可以对更高种类类型的类实例强制执行类型约束?

    我有一个这样定义的类型 newtype PrimeSet a P Integer deriving Eq 我还定义了一个将素数集转换为列表的函数 假设它的类型参数是Integral toList Integral a gt PrimeSet
  • 使用 Template Haskell 生成函数

    是否可以使用 Template Haskell 定义函数 例如 convertStringToValue String gt Int convertStringToValue three 3 convertStringToValue fou
  • 从 createProcess 外部获取的句柄读取

    我正在尝试创建一个进程 并通过我在外部提供的句柄与其进行通信createProcess功能 stdOutH lt openFile logDir gt stdout log ReadWriteMode hSetBuffering stdOu
  • 在 Haskell/Yampa 和 HOOD 中调试游戏对象的输出

    我一直坚持使用 Haskell Yampa Arrows with HOOD 为我的游戏对象生成调试输出 我的引擎基本上运行一系列游戏对象 这些对象产生输出状态 线 圆 然后进行渲染 data Output Circle Position2
  • 在 Haskell 中提升 State monad 中的值

    我正在 Haskell 中编写一个数独生成器 求解器作为学习练习 My solve函数接受一个UArray但返回一个State Int UArray 这样它也可以返回解决问题时发现的最大难度级别 到目前为止 这是我的功能 仍处于实验性的早期
  • 使用 cabal new-install 重新安装相同版本的软件包

    我正在开发 Haskell 包 我还没有上传到Hackage 版本号是0 1 0 0 我正在使用新风格的 Cabal 命令 为了在我处理包的同时测试它 使库可用于测试项目 我运行cabal new install lib构建包后 然而 我注
  • 用parsec解析递归数据

    import Data Attoparsec Text Lazy import Data Text Lazy Internal Text import Data Text Lazy pack data List a Nil Cons a L
  • Haskell 中函数和函子有什么区别?只有定义吗?

    在 Haskell 中 当编写函数时 这意味着我们将某个东西 输入 映射到另一个东西 输出 我尝试 LYAH 来理解 Functor 的定义 看起来和普通 Functor 一样 函数被称为函子有什么限制吗 Functor 是否允许有 I O
  • 通过 Emacs 评估 ghci 或 Hugs 中的缓冲区

    在 Emacs 中使用 sml mode 我已经能够使用以下命令将缓冲区内容直接发送到较差的 SML 进程C c C b 现在我只想用 Haskell 做同样的事情 Haskell 模式似乎不支持这一点 所以我想知道 使用 Emacs 和
  • 访问函数中的环境

    In main我可以读取我的配置文件 并将其提供为runReader somefunc myEnv正好 但somefunc不需要访问myEnv读者提供 链中的下一对也没有提供 需要 myEnv 中某些内容的函数是一个微小的叶函数 如何在不将
  • 如何为强制长度为 2^n 的向量类型定义可用的 Applicative 实例

    对于某些应用程序 我需要长度为 2 n 的向量 为了强制某些操作的长度匹配 我使用 ist 应用实例定义了我的类型 如下所示 LANGUAGE GADTs DataKinds FlexibleInstances FlexibleContex
  • 如何让 Show 显示函数名称?

    作为一个让我熟悉 Haskell 的简单练习 在 Youtube 上闲逛并偶然进入美国倒计时游戏节目之后 我想为数字游戏制作一个求解器 你得到 6 个数字 需要将它们与 为了得到给定的结果 到目前为止我所得到的是非常脑死亡的 let ope
  • 在 Haskell 中增长数组

    我想在 Haskell 中实现以下 命令式 算法 给定一个序列对 e0 s0 e1 s1 e2 s2 en sn 其中 e 和 s 部分不一定是自然数不同的是 在每个时间步都会随机选择该序列的一个元素 例如 ei si 并根据 ei si
  • 将数据类型设置为 Kind * -> * 这不是函子

    布伦特 约尔吉类型分类百科全书 https www haskell org haskellwiki Typeclassopedia给出以下练习 举一个类型的例子 gt 不能将其制成 的实例Functor 不使用undefined 请告诉我什
  • 持久 selectList 导致错误“无法将类型‘BaseBackend backend0’与‘SqlBackend’匹配”

    我遇到以下编译错误 Couldn t match type BaseBackend backend0 with SqlBackend arising from a use of runSqlite The type variable bac
  • Haskell 中的 print 是纯函数吗?

    Is print在 Haskell 中是纯函数 为什么或者为什么不 我认为不是 因为它并不总是返回与纯函数应返回的值相同的值 类型的值IO Int并不是真正的Int 它更像是一张纸 上面写着 嘿 Haskell 运行时 请生成一个Int如此

随机推荐

  • 多重继承的不明确解决方法?

    我有一个名为 动物 的基类 以及继承自 动物 的一只狗和一只猫 还有一个名为dogcat的多重继承类 它继承自dog和cat 在动物中我有一种称为睡眠的方法 当我想使用dogcat的该方法时 我收到错误 DogCat sleep 不明确 我
  • 在 Ubuntu 14.04 上安装 Apache 2.4.7

    我有以下问题 在 Ubuntu 上安装 Apache 2 4 7 我在目录 etc apache2 sites available 中创建了文件
  • 如何将文本与 QTableWidget 中的单元格中心对齐

    我正在使用基于 Qt4 的 PyQt 我的编辑器是 PyCharm 2017 3 我的 python 版本是 3 4 我正在从网站上抓取一些文本 我试图将该文本与 QTableWidget 中单元格的中心对齐 item QTableWidg
  • 结合正则表达式来验证英国和美国的电话号码

    我有两个正则表达式 一个用于验证英国号码 来自我的上一个问题 https stackoverflow com questions 23195191 validate uk phone number including its area co
  • 连续对数算术:游程编码项上的取整运算符

    我正在尝试在 Bill Gosper 上实现基本算术连续对数 https perl plover com yak cftalk INFO gosper txt 它们是连分数的 变异 允许术语协同例程发出和消耗非常小的消息 即使是非常大或非常
  • WPF 列表框分隔符显示为不同的厚度

    我创建了一个自定义列表框 其中每个项目均由分隔符分隔 但我看到了奇怪的问题 列表项之间的分隔符的厚度不是恒定的 如果我改变列表框的位置 它会改变 如下所示列表框图像 https i stack imgur com uKt8n png 下面是
  • 如何禁用 VS datagridview 中的第一个自动选择?

    我在 Visual Studio C 中创建了一个使用 datagridview 的应用程序 现在 当我分配该 datagridview 的数据源时 它会自动选择第一行 并执行我的代码进行选择 由于我经常重新分配该数据源 因此这是不可取的
  • 当 kubectl apply-ing 时替换所有文件中的环境变量

    假设一个文件夹中有许多 Kubernetes 配置文件kubernetes我们希望将它们全部应用 kubectl apply f kubernetes n MyNamespace 其中一些文件包含需要首先替换的环境变量 没有模板化 http
  • 显示和更新 FormArray 内的 FormGroup

    我正在显示带有 ngFor 的 FormArray 我想做的是 当我单击 ngFor 中的某个项目时 用该项目的 任务 属性填充该项目 此外 当我键入 更新输入内容时 原始表单也会被更新 修补 HTML
  • Bash 脚本编写、检查错误、记录日志

    这是为 bash fu 巫师准备的一份 不 实际上 我只是开玩笑 除了我之外 你们可能都知道这一点 我正在尝试创建一个备份 shell 脚本 这个想法相当简单 在某个文件夹中查找超过 7 天的文件 将它们 tar gzip 到另一个目录 然
  • 如何在 Azure ARM 模板中设置环境变量

    我想在 ARM 模板中设置部署环境 以保证机器之间的环境相同 有没有办法为使用 ARM 模板创建的虚拟机设置环境变量 Windows 您可以使用自定义脚本扩展 https learn microsoft com en us azure vi
  • 是否可以在 Android 中将动画 gif 文件设置为我的应用程序的背景?

    我正在为珠宝店做应用程序 我想将 gif 图像设置为我的应用程序的背景 可以设置吗 是的 您可以设置 gif 图像 但这不会为您的 gif 图像设置动画 您需要将 gif 图像显式提取到所有帧中 然后使用动画图像作为 gif 这里是示例
  • 最快的跨平台 A* 实施?

    有这么多可用的实现 使用小网格的 C 执行速度最快 CPU 占用最少 二进制文件最小 跨平台 Linux Mac Windows iPhone A 实现是什么 实施 谷歌返回 http www heyes jones com astar h
  • C++ Boost Graph Library:输出自定义顶点属性

    我正在努力寻找一位定制房产作家与 BGL 合作 struct IkGraph VertexProperty int id int type std pair
  • 随着 TestFlight 被 iTunes Connect 取代,企业应用 Beta 测试将会发生什么?

    我在 中找不到任何有关企业 Beta 测试的信息iTunes Connect 开发人员指南 https developer apple com library ios documentation LanguagesUtilities Con
  • 扩展jQuery的ajax功能

    我想扩展 ajax 函数 以便每当调用它时 页面上就会出现一个图像 指示正在加载内容 我可以使用本页讨论的预过滤器http api jquery com extending ajax http api jquery com extendin
  • 在 WinDbg 中定义自定义错误检查代码

    有没有一种方法可以定义自定义代码 带有消息 描述等 以便当我在 Windows 的内核模式驱动程序中调用KeBugCheckEx要发出自定义 BugCheck 代码 WinDbg 会显示该自定义 BugCheck 代码附带的关联消息吗 有关
  • 使用虚拟目录将 ASP.NET MVC 部署到 IIS 5/6

    我有一个 asp net MVC 应用程序 我想使用虚拟目录将其部署到 IIS 5 和 或 6 我已经执行了通配符路由 但相对路径有问题 假设我创建了一个名为 myApp 的虚拟目录 部署后我可以去http localhost myApp
  • pandas DataFrame旋转问题

    我有一些格式有点奇怪的雷达数据 我不知道如何使用 pandas 库正确地旋转它 My data speed time loc A 63 0000 B 61 0000 C 63 0000 D 65 0000 A 73 0005 B 71 00
  • FreeT 生成的解释器 monad 转换器的 MonadFix 实例?

    我有一个由以下命令生成的标准解释器 monad 转换器的简化版本FreeT data InteractiveF p r a Interact p r gt a type Interactive p r FreeT InteractiveF