Output using higher type variables

Let's say I have a polymorphic type, where one of the parameters is a higher type ( * -> * ).

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

Is there a general way to get instances for these types without using secret and unsafe language extensions?

I tried turning on StandaloneDeriving so that I could specify the context:

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

But the GHC then complains that the restriction is no less than the head of the instance, and points me toward UndecidableInstances .

Summarizing:

1. Should I just accept this advice or is there a better way?

2. Are there any suggestions to facilitate this process?

3. Is it somehow not good to want to output β€œhigher” copies? It would be better to derive instances for several specific types (for example, Vector , [] , Set )

+5
source share
1 answer

1. There is nothing dangerous in UndecidableInstances .

Another way to define Show (Tricky m) requiring m satisfies forall a. Show a => Show (ma) forall a. Show a => Show (ma) . This is fixed by type class

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

An even smarter version of Show1 has been added to the 4.9 Show1 . This is more general because it can be used to display ma when a does not have an instance of Show a .

2. You have found the right pieces for this.

3. No, it plausibly abstracts itself even over higher-grade structures like Vector , [] and Set . Monad transformers are of the form (* -> *) -> (* -> *) and abstract over types of the type (* -> *) , the same as a functor, to create types with the same type as the functor. Tricky has the form (* -> *) -> * , it takes something with the same look as the functor, and creates a regular data type. I call data types of this type β€œModels”, because they abstract the data type by how it is combined.

+8
source

Source: https://habr.com/ru/post/1257546/


All Articles