The type of (forward) rewriting functions in Hoopl is given by the mkFRewrite function:
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
The m type implies that I can use monadic effects while rewriting. The pape开发者_开发知识库r "Hoopl: A Modular, Reusable Library for Dataflow Analysis and Transformation" says the same in Section 4.3, "The rewrite function and the client's monad."
Can anyone give me an example of a rewrite function that has non-Hoopl monadic effects embedded inside it? For example, a rewriter that uses a State monad or does some IO.
This should be pretty simple, just chase the types.
You want a value of FwdRewrite m n f with a custom value of m, so you can pass it to the following function:
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)
So the only constraint on m you have is that it is a CheckpointMonad; then when you run the pass you'll get the final monadic value which you can run yourself.
In fact, GHC's Hoopl passes use with m as a SimplUniqMonad, so we can get fresh labels while we're operating on the graph.
{-# 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
加载中,请稍侯......
精彩评论