Problem when mixing type classes and type families

前端 未结 3 586
梦毁少年i
梦毁少年i 2021-01-02 09:23

This code compiles fine:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDe         


        
相关标签:
3条回答
  • 2021-01-02 09:52

    It means that you aren't allowed to use type synomym families when declaring type instances. See the section "Type families and instance declarations" of the GHC manual.

    The only way you can fix it is to refactor so as to not need it somehow.

    0 讨论(0)
  • 2021-01-02 10:13

    Rec is not a type constructor; it's a type function. Maybe you can use it only in the type of a value of type definition, not in a class declaration? I'm guessing wildly here; I don't understand all the rules for type families.

    I don't know how to fix it, but some things to try include:

    • Get rid of class Sel and just define type family Res a s b :: *. Use type instance instead of the class mechanism.

    • It's barely possible that making type Rec injective using data will help, but I don't think so.

    • Cut back to the smallest number of language extensions that could possibly work—it will make it easier for others to help you, and it might help the compiler as well.

    0 讨论(0)
  • 2021-01-02 10:15

    Type families are one-way: you can expand Rec a to its computed type, but you cannot (uniquely) go from the expansion back to Rec a. This makes applications of type functions unsuitable for instance signatures, as they can never trigger the instance to apply.

    You could try instead:

    instance Rec a ~ reca => Sel a s (b->(c,reca))
    

    This means something else: it says any function b -> (c, reca) is an instance, and then when it has irrevocably matched, the compiler checks that Rec a ~ reca. But this might be good enough to do want in your case.

    0 讨论(0)
提交回复
热议问题