为了使我的Haskell代码采用更通用的模式,需要进行哪些更改?

时间:2018-10-28 02:43:33

标签: haskell

这是我在Haskell中的编码:

(Add (Y 0 3) (Add (Y 1 1) (Y 2 1))) (Add (Y 0 3) (Add (Y 1 1) (Y 2 1)))

如何从输入中使我的代码更通用,从而不受编码限制?

1 个答案:

答案 0 :(得分:0)

可能没有针对设计问题的标准答案。只是一个建议,我怀疑是否适合将data Poli定义为递归类型。

在数学中,多项式只是项的总和,因此,我们可以将多项式定义为

data PolyTerm = X Exponent Coefficient deriving Show
data Poli = Term PolyTerm | Add [PolyTerm] deriving Show

和两个术语的乘积,如前所述:

termMultiple ::PolyTerm -> PolyTerm -> PolyTerm
termMultiple (X e1 c1) (X e2 c2) = (X (e1+e2) (c1*c2)

和两个多项式的乘积可以作为列表理解:

poliMultiple :: Poli -> Poli -> Poli
poliMultiple (Add ps1) (Add ps2)  = 
        Add [ termMultiple t1 t2 | t1 <- ps1, t2 <- ps2]

其他3种情况可以包裹

poliMultiple (Term t1) (Term t2) = Term (termMultiple t1 t2)
poliMultiple (Term p1) ps2@(Add ps) = poliMultiple (Add [p1]) ps2
poliMultiple ps1@(Add ps) (Term p2) = poliMultiple ps1 (Add [p2])

编辑: 由于无法更改Poli的数据类型,因此可能需要将Poli展平并重构为应有的输出模式,如下所示: 添加(X e c(添加(X e c)...添加(X e c)(X e c)))..)

flatten::Poli->[Poli]
flatten t@(Y _ _) = [t]
flatten (Add t@(Y _ _) p) = [t] ++ flatten p
flatten (Add p t@(Y _ _)) = flatten p ++ [t]
flatten (Add p1 p2) = flatten p1 ++ flatten p2

construct::[Poli]->Poli
construct [t]  = t
construct (t:ts) = Add t (construct ts)

和poliMultiple为

poliMultiple (Add p1 p2) (Add p3 p4) = 
    simplify $
        Add (poliMultiple p1 p3) 
            (Add (poliMultiple p1 p4) 
                (Add (poliMultiple p2 p3) (poliMultiple p2 p4)))
    where simplify = construct . flatten

上面(++)的用法是一种效率最低的方法,使用堆栈或将Poli数据类型作为二叉树进行遍历并构造它可能更好。