AST> 1-arity的免费Monad吗?

时间:2019-04-27 12:11:05

标签: haskell compiler-construction category-theory

我说1-arity | 2-arity | n-arity时,是指抓取理论k-ary tree中的树:

  

k元树是一棵有根树,其中每个节点最多有k个子节点

我一直在我的项目中使用Free Monad在haskell中创建一个小型eDSL ...但是我所看到的所有示例都是这样的一元树(线性AST):

enter image description here

此数据类型在Free Monad上提升:

data Toy b next =
    Output b next
  | Bell next
  | Done

我想实现一个比线性eDSL更复杂的eDSL ... Free Monad是否可以解决该问题?如果是,您是否有Free Monad> 1-Ary的示例?

1 个答案:

答案 0 :(得分:7)

具有广义“ arity”概念的树木的表示和组成实际上是自由monads的核心特征之一。

例如,可以将二叉树定义为一个免费的monad,如下所示:

data BinF a = Node a a
type Bin = Free BinF

node :: Bin a -> Bin a -> Bin a
node l r = Free (Node l r)

example :: Bin Int
example = node (node (pure 0)
                     (pure 1))
               (pure 2)
{-
  +---+---0
   \   \--1
    \-2
 -}

同构表示是

data BinF a = Node (Bool -> a)
{- The product type (a, a) is isomorphic to (Bool -> a). -}

其背后的想法是,可以将树节点视为对输入的需求(在这种情况下,是类型为Bool的输入),用于选择节点的子节点之一。因此,二叉树可以看作是比特流的解析器。

type Bin = Free BinF

nextBit :: Bin Bool
nextBit = Free (Node (\b -> Pure b))

example :: Bin Int
example = do
  b1 <- nextBit
  if b1 then do
    b2 <- nextBit
    if b2 then
      pure 0
    else
      pure 1
  else
    pure 2

当然,您可以通过更改Bool类型(或原始公式中Node的字段数)来代表其他领域。

举一个更实际的例子,the pipes library is build around such a free monad