Haskell Hoopl中重写函数内的一元效应示例?

Haskell Hoopl中重写函数内的一元效应示例?,haskell,compiler-construction,monads,dataflow,hoopl,Haskell,Compiler Construction,Monads,Dataflow,Hoopl,中(正向)重写函数的类型由函数给出: mkFRewrite :: (FuelMonad m) => (forall e x. n e x -> f -> m (Maybe (hoopl-3.8.6.1:Compiler.Hoopl.Dataflow.Graph n e x))) -> FwdRewrite m n f analyzeAndRewriteFwd :: forall m n f e x entries.

中(正向)重写函数的类型由函数给出:

mkFRewrite :: (FuelMonad m) => 
   (forall e x.
      n e x
      -> f
      -> m (Maybe (hoopl-3.8.6.1:Compiler.Hoopl.Dataflow.Graph n e x)))
   -> FwdRewrite m n f
analyzeAndRewriteFwd ::
  forall m n f e x entries.
    (CheckpointMonad m,
     NonLocal n,
     LabelsPtr entries) =>
  FwdPass m n f ->
  MaybeC e entries ->
  Graph n e x ->
  Fact e f ->
  m (Graph n e x, FactBase f, MaybeO x f)
m
类型意味着我可以在重写时使用一元效果。论文在第4.3节“重写函数和客户机的monad”中也提到了同样的内容


谁能给我举一个重写函数的例子,其中嵌入了非Hoopl一元效应?例如,使用状态单子或执行某些IO的重写器

这应该很简单,只需追踪类型即可

您希望值为
FwdRewrite m n f
,自定义值为
m
,因此可以将其传递给以下函数:

mkFRewrite :: (FuelMonad m) => 
   (forall e x.
      n e x
      -> f
      -> m (Maybe (hoopl-3.8.6.1:Compiler.Hoopl.Dataflow.Graph n e x)))
   -> FwdRewrite m n f
analyzeAndRewriteFwd ::
  forall m n f e x entries.
    (CheckpointMonad m,
     NonLocal n,
     LabelsPtr entries) =>
  FwdPass m n f ->
  MaybeC e entries ->
  Graph n e x ->
  Fact e f ->
  m (Graph n e x, FactBase f, MaybeO x f)
因此,对
m
的唯一限制是它是一个
检查点monad
;然后,当您运行pass时,您将得到最终的一元值,您可以自己运行它

事实上,GHC的环向传球使用
m
作为
simpleniqmonad
,因此我们可以在图形上操作时获得新的标签

{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE TypeFamilies #-}

import Compiler.Hoopl
import Control.Monad.State

type StateFuel s a = CheckingFuelMonad (State s) a

instance CheckpointMonad (State s) where
    type Checkpoint (State s) = s
    checkpoint = get
    restart = put

正如前一个问题所讨论的,FuelMonad是不透明的:——我认为在这一点上,直接写Hoopl的作者是值得的。我怀疑他们隐藏的内容超出了他们的预期,因此限制了比你所意识到的更多的功能。这也是我的怀疑。Hoopl的第一位作者(和软件包维护者)也有,所以我很惊讶他没有回答这些问题。虽然看起来他最近确实不太活跃了…谢谢你的回答,但我想看看重写函数中的非环形单体效果。我认为您的示例所能展示的最好的方法是使用
检查点
重新启动,
这两个hoop提供的函数。贾斯汀:我仍然不明白:您是否在寻找适合非hoop monadic操作的情况?(这里有一个非常简单的方法:唯一名称生成)或者从技术上讲,如何实际执行(这非常简单,因为重写函数的输出是一个一元操作)。请注意,使用检查点函数是个坏主意,因为Hoop在计算不动点时使用这些函数来保持确定性。我想看看如何做到这一点。我认为您无法实现任何功能,因为
FuelMonad
类的成员是隐藏的,但我希望被证明是错误的。如果您知道代码示例,请指出它们!看来你是对的。从技术上讲,您可以使用自己的monad,但无法访问其任何特殊功能,因为FuelMonad仅有的两个实例没有MonadTrans实例。