Pattern matching within closed type families

I am incompetently trying to play with the new feature of the GHC 7.8 family of private types and I would like to find a good way to branch on type level constructs.

I have something like

data (:::) :: Symbol -> * -> * where

data Result = Pre | Post | Match

type family Cmp a b :: Result where
    Cmp (s ::: t) (s ::: t) = Match
    Cmp (s1 ::: t1) (s2 ::: t2) = ???

where I would like to return different types depending on the result CmpSymbolin GHC.TypeLits. It looks like something like

Cmp (s1 ::: t1) (s2 ::: t2) = (CmpSymbol s1 s2 ~ LT) => Pre
Cmp (s1 ::: t1) (s2 ::: t2) = (CmpSymbol s1 s2 ~ GT) => Post

should work, but it’s not. Interestingly, this is not a syntax error, but instead a complaint that he is sick.

I can somehow make it work using unsolvable instances and a helper function:

type family Cmp a b :: Result where
    Cmp (s ::: t) (s ::: t) = Match
    Cmp (s1 ::: t1) (s2 ::: t2) = Fun (CmpSymbol s1 s2)

type family Fun r :: Result where
    Fun LT = Pre
    Fun GT = Post

, , ? ghci - :kind! Cmp ("a" ::: Int) ("a" ::: String) Fun 'EQ Fun . ? ? , Fun -

class Fun2 o r
instance Fun2 LT Pre
instance Fun2 GT Post

, , Fun?

+4
1

, (== If), If (CmpSymbol s1 s2 == LT) Pre Post.

, LT -> Pre , Fun2.

kind Fun EQ, CmpSymbol "a" "a" EQ, Fun. , , - , - "" Fun EQ, .

+2

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


All Articles