Я хочу сделать тип пары для представления модульной арифметики c. Я сделал его конструктор
{- LANGUAGE GADTs -}
data Zn e where
Zn :: Integer -> Integer -> Zn Integer
, потому что я хотел бы иметь возможность fmap
над ним и всеми вещами. Поэтому, если я попытаюсь сделать его экземпляром Functor
instance Functor Zn where
fmap f (Zn s n) = Zn s $ mod (f n) s
, я получу Could not deduce: b ~ Integer from the context: a ~ Integer
. Конечно, он не может вывести это, потому что этот тип данных не имеет осмысленного понятия fmap :: (a -> b) -> Zn a -> Zn b
для всех a
и b
, но это происходит всякий раз, когда a
и b
таковы, что на самом деле можно построить Zn
экземпляры из них (ie Integer
). Я также попытался использовать конструктор Zn
, и для всех методов требуется Integral e
, но у меня возникает похожая проблема. В этом случае s
имеет тип a
, поэтому создание Zn
с ним и f n :: b
завершится неудачей. Во втором случае я мог бы преобразовать s
из a
в Integer
, а затем в b
, но это неуклюже. Все это немного неуклюже. Я просто делаю это, потому что хочу иметь возможность реализовать Functor
и Applicative
для выполнения mod
после сопоставления функции, чтобы я мог просто реализовать +
как liftA2 (+)
и так далее. Модуль s
должен быть частью типа, но, насколько я знаю, зависимые типы непрактичны в Haskell.
Возможно ли иметь тип с видом * -> *
Implement Functor
для некоторых аргументов?