Print argument order for declaring an instance in Haskell

I want to make an instance declaration, but the free type variable is not the last variable. For example, I have a class declaration

class Poppable m where
  tryPop :: m a -> Maybe (a, m a)

Now I want to make Q.PSQ (priority queue) an instance of Poppable. In particular, I want something like this:

instance (Ord p) => Poppable (\a -> Q.PSQ a p) where
  tryPop = fmap (first Q.key) . Q.minView

However, this is not legal Haskell code. If the order of the arguments in PSQ were switched, then I would not have problems:

instance (Ord p) => Poppable (Q.PSQ p) where
  tryPop = fmap (first Q.key) . Q.minView

How to switch argument order for instance declaration?

Now I can wrap the PSQ with a new type:

newtype PSQ'' a b = PSQ'' (Q.PSQ b a)

However, this seems awkward for me, because I have to constantly wrap / unwrap it. Is there an easier way?

*

I tried using data / type families, but both of them give errors.

(1) Using a data collection declaration:

data family PSQ' a b
data instance PSQ' a b = PSQ b a
instance (Ord p) => Poppable (PSQ' p) where
  tryPop = fmap (first Q.key) . Q.minView

However this gives an error

Couldn't match type `Q.PSQ a p0' with `PSQ' p a'

, p = p0.

(2) .

type family PSQ' a b where
  PSQ' b a = Q.PSQ a b

Illegal type synonym family application in instance: PSQ' p
+4
2

PSQ :

newtype PSQ'' a b = PSQ'' (Q.PSQ b a)

, /. ?

, . , , Poppable, PSQ. ,

newtype Flip f a b = Flip (f b a)

instance Poppable (Flip Q.PSQ a)

. , Haskell (, , ..), .

P.S., , {-# LANGUAGE PolyKinds #-},

newtype Flip (f :: k1 -> k2 -> *) (a :: k2) (b :: k1) = Flip (f b a)
+8

, " ":

class Poppable q where
  type Elem q 
  tryPop :: q -> Maybe (Elem q, q)

data PSQ a p = ... 

instance Ord p => Poppable (PSQ a p) where 
  type Elem (PSQ a p) = a 
  tryPop = ...

, , .

+2

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


All Articles