首页 > 解决方案 > 需要进行哪些更改才能使我的 Haskell 代码采用更通用的模式?

问题描述

这是我在 Haskell 中的编码:

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

如何从输入中使我的代码更通用模式,使其不像我的编码那样受到限制?

标签: haskell

解决方案


设计问题可能没有标准答案。只是一个建议,我怀疑是否适合定义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 展平并重构为应得的输出模式: Add (X ec (Add (X ec) ... Add (X ec) (X ec) ))..)

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数据类型作为二叉树来遍历构造可能会更好。


推荐阅读