Я почти уверен, что об этом уже спрашивали раньше, однако мне не удалось найти правильный ответ:
Я попытался устранить двусмысленность в следующем примерном Фрагмент кода:
{-# LANGUAGE MultiParamTypeClasses #-}
class FooBar a b where
foo :: a -> a
foo = id
bar :: a -> a
bar = foo -- ERROR AT THIS LINE
Я получаю такое сообщение об ошибке:
Ambiguous type variable `b0' in the constraint:
(FooBar a b0) arising from a use of `foo'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: foo
In an equation for `bar': bar = foo
, что понятно. Однако обратите внимание, что я фактически не могу последовать совету компилятора и исправить рассматриваемую переменную типа: foo
не содержит переменную типа b
в своей сигнатуре типа. Также это не работает:
bar = (foo :: FooBar a b => a -> a) -- ERROR, the same error message
Даже с включенным -XScopedTypeVariables
.
Как указать GHC, какой FooBar использовать? Возможно ли это вообще?
РЕДАКТИРОВАТЬ
После нескольких ответов: да, я слышал как о функциональных зависимостях, так и о связанных типах.
Что касается функциональных зависимостей - я ищу способ явно сообщить GHC, какой экземпляр использовать (вместо того, чтобы просить его самостоятельно получить правильный тип).
Что касается обоих - в реальном примере, из которого взят этот, мне действительно нужно, чтобы оба параметра a
и b
были независимыми.
Опять же: я знаю, что этот пример чрезвычайно глуп, я знаю, что b
не используется в теле класса типа, что не имеет смысла. Это крайнее упрощение реального примера, которое действительно имеет смысл. Реальный вариант использования включает «заменяемость» типов a
с использованием типов b
, а затем «унифицируемость» типов a
и b
с использованием типы c
и, к сожалению, намного длиннее.
РЕДАКТИРОВАТЬ (2)
Ладно, извините. Думаю, вы убедили меня в том, что я должен провести рефакторинг кода, чтобы не было каких-либо плохо определенных функций (т.е. тех, которые не содержат всех независимых типов в своих сигнатурах типов). Хотя разговор с тобой действительно помог мне подумать об этом. Оценил.