У меня есть тип данных Polynomial r для полиномов в Haskell и экземпляр Ring для него. (class Ring r where plus :: r -> r -> r ; times :: r -> r -> r ; negative :: r -> r ; zero :: r ; one :: r
- это просто упрощенная версия Num).Определение типа данных, который не требуется определять
Теперь я мог определить полином, такие как gauss = x^2 + 1
или eisenstein = x^2 + x + 1
, а затем работать в «полиномиального Integer/(гс)» для гауссовых целых чисел или «полиномиальной Integer/(Эйзенштейн)» для целых чисел Эйзенштейна. В этом проблема, я написал ее в кавычках, потому что это не настоящий тип данных, и я не могу понять, как ее определить.
я первый попытался сделать что-то вроде data Quotient p = Quot p p
, а затем, например, мы бы plus (Quot a i) (Quot b i') | i == i' = Quot (plus a b) i
Конечно, это очень плохо, но уже это даже не представляется возможным определить one
и zero
. Поэтому я изменил его на data Quotient p = Quot p (Maybe p)
, и я думаю, что у меня есть рабочая реализация, но вы точно не знаете, будет ли работать plus
(ему нужно хотя бы один Just
, а если их два, то они должны быть одинаковыми).
Есть ли какой-либо тип безопасного (я имею в виду не использовать небезопасные функции) способ программирования этого в haskell? Я довольно тупой. Благодаря!
Я думаю, что вы действительно хотите [зависимые типы] (http://en.wikipedia.org/wiki/Dependent_type) (которых нет в Haskell); это позволит вам сказать что-то вроде 'data Quotient (p :: *) (q :: Polynomial r) = Quot p', где тип данных параметризуется значением. В этом случае может быть способ подражать ему, но я не уверен. –
Вы посмотрели на цифровую прелюдию, http://hackage.haskell.org/package/numeric-prelude-0.2? Они проделали большую работу по решению подобных проблем. –
@Antal, я думаю, что ваш 'Quotient' будет работать, если вы использовали новый тип для каждого многочлена. Звучит как боль. –