Я почти уверен, что об этом уже спрашивали, однако мне не удалось найти правильный ответ:
Я попытался устранить неоднозначность в следующем примерном фрагменте кода:
{-# 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
не используется в теле класса type, что не имеет смысла.Это крайнее упрощение примера из реального мира, которое действительно имеет смысл.Реальный вариант использования включает в себя «заменяемость» типов a
с использованием типов b
и затем «унифицируемость» типов a
и b
с использованием типов c
и, к сожалению, намного длиннее.
РЕДАКТИРОВАТЬ (2)
Хорошо, извините.Я думаю, что вы все-таки убедили меня, что я должен реорганизовать код, чтобы не иметь каких-либо плохо определенных функций (то есть тех, которые не содержат всех независимых типов в сигнатурах их типов).Разговор с тобой действительно помог мне подумать об этом.Оценил.