Связано с this question Я спросил сегодня.Производя экземпляр functor, а не аргумент последнего типа
У меня есть тип AST данных с большим числом случаев, которое спараметрированное с помощью «аннотаций» типа
data Expr ann def var = Plus a Int Int
| ...
| Times a Int Int
deriving (Data, Typeable, Functor)
Я получил конкретные примеры для четкости и вара, скажу Def
и Var
.
Я хочу, чтобы автоматически выводить fmap
, который работает как функтор по первому аргументу. Я хочу, чтобы получить функцию, которая выглядит следующим образом:
fmap :: (a -> b) -> (Expr a Def Var) -> (Expr b Def Var)
Когда я использую нормальный fmap
, я получаю сообщение компилятора, который указывает БПМЖ пытается применить свои функции до последнего типа аргумента, а не первым.
Есть ли способ, который я могу получить, как описано, без написания кучи шаблона? Я попытался сделать это:
newtype Expr' a = E (Expr a Def Var)
deriving (Data, Typeable, Functor)
Но я получаю следующее сообщение об ошибке:
Constructor `E' must use the type variable only as the last argument of a data type
Я работаю с чужой код базы, так что было бы идеально, если бы я не должен переключить порядок аргументов типа всюду.
Вы можете сделать безобразный хак, где вы определить другой, одинаковый тип с аргументами типа в правильный порядок, выведите экземпляр Functor для этого, а затем используйте 'unsafeCoerce'. Это действительно очень плохо, и я не рекомендую его.Самый простой вариант - сворачивать свои собственные функции вывода; или просто реорганизовать существующий код. Если вы не возражаете потянуть большую зависимость, посмотрите на пакет [получить] (http://hackage.haskell.org/package/derive-2.5.5/docs/Data-Derive-Functor.html) , – user2407038
'Expr ann def' не может иметь экземпляр« Functor », если' var' - это переменная типа, которая изменяется с помощью 'fmap'. – Cirdec
Жаль, что для пакета 'hask' нет функции типа DeriveFunctor. Пакет 'hask' предоставляет, среди прочего, поликинный класс типа« Functor », который способен« fmap »поверх переменных типа глубже первого (до тех пор, пока все переменные типа справа от него имеют« Functor » а также, похоже, в этом случае было бы тривиально верно). –