Нет, ваша подпись типа, которая на самом деле
forall a b. (Eq a, Eq b) => a -> b
означает, что ваша функция должна вызываться с любыми типами a
и b
, как определено call site , если оба являются экземплярами Eq
.
Не ваша функция решает, какой тип вернуть. Это использование вашей функции , который определяет это.
Таким образом, вы должны иметь возможность написать
let { i :: Int; i = 1;
n :: Integer; y :: Double;
n = foo i; -- foo :: Int -> Integer
y = foo i -- foo :: Int -> Double
}
, и, как вы можете видеть, единственная реализация для вашей функции - это нет реализация:
foo _ = x where {x = x}
, потому что у вас нет возможности получить значение любого типа , которое от вас требуется.Этот тип может быть любым, и вы ничего не можете о нем знать.
Кстати, другие классы типов могут фактически позволить вам определить что-то здесь, как
foo :: (Enum a, Enum b, Bounded a, Bounded b) => a -> b
foo a = snd . last $ zip [minBound .. a] (cycle [minBound ..])
Я не говорю, что это разумное определение, просто оно возможно:
> foo () :: Bool
False
> foo True :: Int
-9223372036854775807
> foo (0 :: Int) :: Bool
Interrupted.
Это, вероятно, распространенное заблуждение для программистов, исходящих из более привычныхЯ думаю, что foo :: (Eq a) => a
означает «я могу определить foo
, чтобы вернуть любой тип, который я хочу, до тех пор, пока он находится в Eq
».Это не так.:)