haskell - 需要进行哪些更改才能使我的 Haskell 代码采用更通用的模式?
问题描述
这是我在 Haskell 中的编码:
(Add (Y 0 3) (Add (Y 1 1) (Y 2 1))) (Add (Y 0 3) (Add (Y 1 1) (Y 2 1)))
如何从输入中使我的代码更通用模式,使其不像我的编码那样受到限制?
解决方案
设计问题可能没有标准答案。只是一个建议,我怀疑是否适合定义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数据类型作为二叉树来遍历构造可能会更好。
推荐阅读
- javascript - 关于分页符,如何让 Puppeteer PDF 生成与 HTML 文档完全匹配?
- r - 我正在尝试在 devtools 包中使用 install_github 但失败了
- javascript - 在 JavaScript 中使用谓词函数进行匹配
- javascript - 将高阶函数称为“模板”是否正确?
- git - git 强制将本地文件放在原点之上
- c++ - C++ 中闭包的返回类型
- javascript - 在 chrome 扩展中提交表单时弹出刷新
- prolog - 如何让我的迷宫程序创建两个路线列表并将其打印到控制台?
- mysql - 尝试使用 select 语句向存储过程中的变量添加值
- r - 修改 flexdashboard 的 shinyauthr