Вывод с использованием переменных более высокого типа

#haskell #ghc #type-kinds

#haskell #ghc #тип-виды

Вопрос:

Допустим, у меня есть полиморфный тип, где одним из параметров является тип с более высоким типом ( * -> * ) .

 data Tricky m = Tricky { numbers :: m Int, genesis :: m String }
  

Существует ли общий способ получения экземпляров для таких типов без использования тайных и небезопасных языковых расширений?

Я попытался включить StandaloneDeriving , чтобы я мог указать контекст:

 deriving instance Show (m Int) => Show (Tricky m)
  

Но затем GHC жалуется на то, что ограничение не меньше, чем заголовок экземпляра, и указывает мне в направлении UndecidableInstances .

Подводя итог:

1. Должен ли я просто согласиться с этим советом или есть лучший способ?

2. Есть ли какие-либо предложения по упрощению этого процесса?

3. Является ли каким-то неправильным желанием создавать экземпляры с более высоким типом? Было бы лучше вместо этого создавать экземпляры для нескольких конкретных типов (например, Vector , [] , Set )

Ответ №1:

1. В этом нет ничего небезопасного UndecidableInstances .

Есть еще один способ определения Show (Tricky m) , который заключается в том, чтобы требовать m удовлетворения forall a. Show a => Show (m a) . Это фиксируется классом типов, например

 class Show1 f where
    showsPrec1 :: Show a => Int -> f a -> ShowS
  

В базу 4.9 добавлена еще более умная версия Show1 . Он более общий, поскольку его можно использовать для отображения m a , когда a у него нет Show a экземпляра.

2. Вы нашли правильные фрагменты для этого.

3. Нет, правильно абстрагироваться от еще более высоких структур, таких как Vector , [] , и Set . Преобразователи монад имеют вид (* -> *) -> (* -> *) и абстракцию над типами вида (* -> *) , того же типа, что и функтор, для создания типов с тем же типом, что и функтор. Tricky имеет вид (* -> *) -> * , он принимает что-то с тем же видом, что и функтор, и создает обычный тип данных. Я называю типы данных такого рода «Моделями», поскольку они создают тип данных, абстрагирующийся от того, как он составлен.