我说1-arity | 2-arity | n-arity
时,是指抓取理论k-ary tree中的树:
k元树是一棵有根树,其中每个节点最多有k个子节点
我一直在我的项目中使用Free Monad在haskell中创建一个小型eDSL ...但是我所看到的所有示例都是这样的一元树(线性AST):
此数据类型在Free
Monad上提升:
data Toy b next =
Output b next
| Bell next
| Done
我想实现一个比线性eDSL更复杂的eDSL ... Free Monad是否可以解决该问题?如果是,您是否有Free Monad> 1-Ary的示例?
答案 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。