【问题标题】:Syntax trees: free monad + Bound.Scope语法树:free monad + Bound.Scope
【发布时间】:2014-12-12 00:00:37
【问题描述】:

我正在尝试使用 ekmett 的库 boundfree 定义抽象语法类型。我有一些工作,我可以将其简化为以下最小示例:

{-# 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')

最后两行,呃,不是我所希望的。他们使它成为一种 PITA,以实际利用注释(或其他)的开放递归。

有没有更好的方法将这两个库一起使用,和/或我是否应该放弃尝试使 Term 成为免费的 monad?

【问题讨论】:

    标签: haskell abstract-syntax-tree free-monad


    【解决方案1】:

    让它变得简单

    你可以把最后两行简化成。

    newtype Term α = T {unT :: Free (TermF Term) α}
    

    这应该可以帮助您知道在任何地方都始终如一地使用TunT,而不仅仅是在其他级别。

    让事情变得复杂

    FreeTermF 都有(*->*)->(*->*) 类型,这是一种变压器。您正在寻找FreeTermF 组合的不动点。我们可以写出一般的transformer的组成。

    {-# LANGUAGE PolyKinds #-}
    
    newtype ComposeT g h f a = ComposeT { unComposeT :: g (h f) a}
        deriving Functor
    

    我们也可以写出一般变换器的不动点。

    {-# 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)
    

    那么你可以写

    type Term = FixT (ComposeT Free TermF)
    

    然后在您将使用T 的任何地方使用FixT . ComposeT,在您将使用unT 的任何地方使用unComposeT . unFixT

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 2018-08-22
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多