Допустим, у меня есть класс:
class C a where
reduce :: a -> Int
Теперь я хочу упаковать его в тип данных:
data Signal = forall a. (C a) => Signal [(Double, a)]
Спасибо Что касается экзистенциальной количественной оценки, я могу вызывать методы C в сигналах, но сигналы не предоставляют параметр типа:
reduceSig :: Signal -> [(Double, Int)]
reduceSig (Signal sig) = map (second reduce) sig
Теперь, поскольку у C есть несколько методов, моим естественным следующим шагом будет вытащить функцию 'уменьшить', чтобы я мог подставьте любой метод:
mapsig :: (C a) => (a -> a) -> Signal -> Signal
mapsig f (Signal sig) = Signal (map (second f) sig)
Ошибка типа! Не удалось вывести (a1 ~ a). Поразмыслив, я думаю, он говорит о том, что 'f' является функцией некоторого экземпляра C, но я не могу гарантировать, что это тот же экземпляр C, что и в Signals, потому что параметры типа скрыты! Я хотел этого, я получил это.
Значит ли это, что обобщение reduceSig невозможно? Я могу с этим жить, но я так привык к свободному выделению функций в haskell, что мне кажется странным быть обязанным писать шаблон. С другой стороны, я не могу придумать никакого способа выразить, что тип равен типу внутри Signal, за исключением предоставления Signal параметра типа.