Я играл с FunctionalDependencies-Extension Haskell вместе с MultiParamTypeClasses. Я определил следующее:
class Add a b c | a b -> c where
(~+) :: a -> b -> c
(~-) :: a -> b -> c
neg :: a -> a
zero :: a
который отлично работает (я пробовал с экземплярами для Int и Double с конечной целью иметь возможность добавлять Int и Doubles без явного преобразования).
Когда я пытаюсь определить реализации по умолчанию для neg или (~-) следующим образом:
class Add ...
...
neg n = zero ~- n
GHCi (7.0.4) говорит мне следующее:
Ambiguous type variables `a0', `b0', `c0' in the constraint:
(Add a0 b0 c0) arising from a use of `zero'
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `(~-)', namely `zero'
In the expression: zero ~- n
In an equation for `neg': neg n = zero ~- n
Ambiguous type variable `a0' in the constraint:
(Add a0 a a) arising from a use of `~-'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: zero ~- n
In an equation for `neg': neg n = zero ~- n
Я думаю, что понимаю проблему здесь. GHC не знает, какой ноль использовать, поскольку это может быть любой ноль, дающий что-либо, что, в свою очередь, передается в ~-
, о котором мы знаем только, что он имеет a
в правильном аргументе и дает a
.
Итак, как я могу указать, что это должен быть ноль из того же самого экземпляра, т.е. как я могу выразить что-то вроде:
neg n = (zero :: Add a b c) ~- n
Я думаю, что a
, b
и c
здесь не a b c формируют окружающий класс, а любые a b и c, так как я могу выразить тип, который является ссылкой на локальные переменные типа?