Библиотека Haskell, такая как SymPy?
Мне нужно манипулировать выражениями вроде 1 + sqrt (3) и выполнять базовую арифметику, такую как сложение, вычитание и деление. Я хотел бы, чтобы результат был в какой-то канонической форме, чтобы его можно было использовать в качестве ключа на карте. Поворот 1 + sqrt (3) в поплавок невозможен из-за проблем округления.
Я использовал SymPy для этой задачи в Python. Есть ли эквивалентная родная библиотека для Haskell?
Ответы
Ответ 1
Кажется, вы ищете компьютерную алгебраическую систему (CAS) в Haskell. Несмотря на столько ссылок на алгебраические объекты в именах пакетов/модулей Haskell, я никогда не слышал об общей цели и ухоженной системе CA в Haskell (например, SymPy или Sage в Python).
Однако в списке систем компьютерной алгебры в Википедии я нашел ссылку на
DoCon. Алгебраический конструктор доменов
Он использует нестандартную лицензию, но я осмелюсь сказать, что он по-прежнему является Open Source (хотя с переименованием и атрибутами). По состоянию на июль 2010 года docon-2.11
по-прежнему строит с GHC 6.12.1 и запускает демонстрационные версии/тесты (мне нужно было вставить прагму LANGUAGE FlexibleContexts
в один файл демо).
DoCon хорошо документирован (362 страницы Руководства). Его Руководство упаковано внутри zip с источниками, поэтому я поместил его онлайн отдельно для удобства:
DoCon 2.11 Manual.ps
Пожалуйста, проверьте, подходит ли оно для ваших нужд.
Ответ 2
Пожалуйста, проверьте пакет 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, но в описании говорится: "Он в основном полезен для отладки".
Ответ 3
Посмотрите cyclotomic пакет, который реализует точную арифметику по круговым числам. К ним относятся все алгебраические числа (следовательно, в частности 1 + sqrt (3)), а ключевые операции (например, равенство) разрешимы.
Они не предоставляют экземпляр Ord
(по той же причине, что и комплексные числа), но можно реализовать не семантический экземпляр, если все, что ему нужно, - использовать их в качестве ключей в справочной таблице. Вы можете связаться с автором о том, как это сделать правильно, так как могут быть некоторые инварианты, которые не являются очевидными (например, может быть нужно быть осторожным относительно нулей на карте coeffs
).