And*_*ris 9 haskell abstract-syntax-tree free-monad
我试图定义使用ekmett的库抽象语法类型bound和free.我有一些工作,我可以删除到以下最小的例子:
{-# LANGUAGE DeriveFunctor #-}
import Bound
import Control.Monad.Free
type Id = String
data TermF f ? =
AppF ? ?
| BindF Id (Scope () f ?)
deriving Functor
newtype Term' ? = T {unT :: Free (TermF Term) ?}
type Term = Free (TermF Term')
Run Code Online (Sandbox Code Playgroud)
最后两行是,呃,不是我所希望的.它们使得PITA实际上可以利用注释(或其他)的开放递归.
是否有更好的方法将这两个库一起使用,和/或我应该放弃尝试制作Term一个免费的monad?
您可以将最后两行简化为.
newtype Term ? = T {unT :: Free (TermF Term) ?}
Run Code Online (Sandbox Code Playgroud)
这应该可以帮助您确保始终如一地使用T,unT而不是仅在其他所有级别使用.
双方Free并TermF有那种(*->*)->(*->*),它是那种一个变压器.您正在寻找的组成的固定点Free和TermF.我们可以编写一般的变压器组成.
{-# LANGUAGE PolyKinds #-}
newtype ComposeT g h f a = ComposeT { unComposeT :: g (h f) a}
deriving Functor
Run Code Online (Sandbox Code Playgroud)
我们也可以编写变压器的固定点.
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
newtype FixT t a = FixT { unFixT :: t (FixT t) a }
deriving instance Functor (t (FixT t)) => Functor (FixT t)
Run Code Online (Sandbox Code Playgroud)
然后你可以写
type Term = FixT (ComposeT Free TermF)
Run Code Online (Sandbox Code Playgroud)
然后使用FixT . ComposeT您刚刚使用的任何地方T以及unComposeT . unFixT您将使用的任何地方unT.
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |