haskell-类型-函数-树
对于haskell的练习,我想实现一个游戏,在这个游戏中,学生/学生应该好玩地学习一些代数 作为基本数据类型,我希望使用树:haskell-类型-函数-树,haskell,types,tree,Haskell,Types,Tree,对于haskell的练习,我想实现一个游戏,在这个游戏中,学生/学生应该好玩地学习一些代数 作为基本数据类型,我希望使用树: 具有存储了标签和代数运算符的节点 具有标签和变量(类型字符串)或数字的叶子 现在我想定义一下 data Tree = Leaf {l :: Label, val :: Expression} | Node {l :: Label, f :: Fun, lBranch :: Tree, rBranch :: Tree} data Fun = "on
- 具有存储了标签和代数运算符的节点
- 具有标签和变量(类型字符串)或数字的叶子
data Tree = Leaf {l :: Label, val :: Expression}
| Node {l :: Label, f :: Fun, lBranch :: Tree, rBranch :: Tree}
data Fun = "one of [(+),(*),(-),(/),(^)]"
-- type Fun = Int -> Int
行得通
我想的下一件事是使树“等价”——因为乘法/加法是可交换的,人们可以简化乘法的加法等所有代数运算。
我还必须通过搜索树-我认为是最好的标签,这是一个好办法
有什么想法需要寻找什么标签/短语以及如何解决“数据乐趣”看起来你想构建一个符号代数系统。关于这个问题有大量不同的文献
您不希望将运算符表示为
Int->Int
,因为这样您就无法检查任何给定函数实现的操作,然后为简化等操作实现窥视孔优化。因此,一个简单的枚举数据类型就可以做到这一点,然后编写函数eval
,该函数实际计算您的树。展开Edward Z.Yang的回答:
这里定义运算符的最简单方法可能是作为数据类型,以及叶节点中原子值的类型和整个表达式树:
data Fun = Add | Mul | Sub | Div | Exp deriving (Eq, Ord, Show)
data Val a = Lit a | Var String deriving (Eq, Ord, Show)
data ExprTree a = Node String Fun (ExprTree a) (ExprTree a)
| Leaf String (Val a)
deriving (Eq, Ord, Show)
然后,您可以将exprtreea
定义为Num
等的实例:
instance (Num a) => Num (ExprTree a) where
(+) = Node "" Add
(*) = Node "" Mul
(-) = Node "" Sub
negate = Node "" Sub 0
fromInteger = Leaf "" . Lit
…允许以非常自然的方式创建未标记的表达式:
*Main> :t 2 + 2
2 + 2 :: (Num t) => t
*Main> 2 + 2 :: ExprTree Int
Node "" Add (Leaf "" (Lit 2)) (Leaf "" (Lit 2))
另外,请注意上面关于数据定义的派生
条款,特别是Ord
;这会告诉编译器自动为该类型的值创建排序关系。这使您可以一致地对它们进行排序,这意味着您可以,例如,在子表达式上定义规范顺序,以便在重新排列交换操作时,您不会陷入循环中。给定一些规范化约化和规范化顺序的子表达式,在大多数情况下,您将能够使用Eq
给出的自动相等关系来检查子表达式的等价性
请注意,标签将影响此处的顺序和相等性。如果不希望这样,您需要为Eq
和Ord
编写自己的定义,就像我为Num
给出的定义一样
之后,您可以编写一些遍历和归约函数,以执行诸如应用运算符、执行变量替换等操作