полиморфная функция по экзистенциальному типу

Допустим, у меня есть класс:

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 параметра типа.

14
задан Evan Laforge 17 December 2011 в 05:32
поделиться