31

I need to manipulate expressions like 1 + sqrt(3) and do basic arithmetic like addition, subtraction, and division. I'd like the result to be in some sort of canonical form so that it can be used as a key in a map. Turning 1 + sqrt(3) into a float is not feasible due to roundoff problems.

I used SymPy for this task in Python. Is there an equivalent native library for Haskell?

4

3 回答 3

9

看来您正在 Haskell 中寻找计算机代数系统 (CAS)。尽管在 Haskell 包/模块的名称中引用了这么多代数对象,但我从未听说过 Haskell 中有一个通用且维护良好的 CA 系统(如 Python 中的 SymPy 或 Sage)。

然而,在维基百科上的计算机代数系统列表中,我找到了对

多康。代数域构造器

它使用非标准许可证,但我敢说它仍然是开源的(尽管有重命名和归属要求)。截至 2010 年 7 月,docon-2.11仍然使用 GHC 6.12.1 构建并运行演示/测试(我只需LANGUAGE FlexibleContexts在演示的一个文件中插入一个编译指示)。

DoCon 有据可查(手册的 362 页)。它的手册包含在 zip 中并附有源代码,因此为了方便起见,我将其单独放在网上:

DoCon 2.11 手册.ps

请仔细检查它是否适合您的需求。

于 2010-07-21T13:34:33.563 回答
9

numbers检查包裹。如果您只需要存储“1 + √3”之类的精确数字,则可能需要使用Data.Number.CReal而不是符号算术。它存储表达式,并且可以在需要时计算到任意位数。

Prelude Data.Number.CReal> let cx = 1 + sqrt (3 :: CReal)
Prelude Data.Number.CReal> showCReal 400 cx 
"2.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067030299699450949989524788116555120943736485280932319023055820679748201010846749232650153123432669033228866506722546689218379712270471316603678615880190499865373798593894676503475065760507566183481296061009476021871903250831458295239598329977898245082887144638329173472241639845878553977"

包中还有一个 Data.Number.Symbolic 模块,但描述说“它主要用于调试”。

于 2010-07-21T11:29:07.243 回答
4

查看cyclotomic包,它实现了对分圆数的精确算术。这些包括所有代数数(因此特别是 1+sqrt(3))和关键操作(如相等)是可判定的。

它们不提供Ord实例(与复数不提供的原因相同),但如果所有人都需要将它们用作查找表中的键,则可以实现非语义实例。您可能想联系作者以了解如何正确执行此操作,因为可能存在一些不明显的不变量(例如,可能需要注意coeffs地图中的零)。

于 2015-01-09T18:51:37.470 回答