Type-threaded heterogenous lists and defaulting(?) with type families?

前端 未结 2 907
礼貌的吻别
礼貌的吻别 2020-12-17 06:00

I\'m working on a library where I want to define a recursive class that I\'ve simplified here to:

{-# LANGUAGE MultiParamTypeClasses 
           , FlexibleIn         


        
相关标签:
2条回答
  • 2020-12-17 06:37

    The answer to the linked question hides the following quite useful trick: generalize the instance head, and specialize in the instance context.

    instance a ~ b => StackTo a Top b where
        runStack _ = id
    

    When choosing an instance to use, GHC inspects available instance heads only -- not contexts -- and picks the one (if any) that matches what is currently known about a type. It will not specialize a type before making this choice, even if specializing would allow one or more of the available instance heads to match. Thus, the difference between the instance given here and the one in the question above is that this one is more general: this one applies whenever the middle type is Top, whereas yours applies only when the middle type is Top and we know enough about the two other types to know they're equal.

    Yours will overlap with fewer other potential instances, but this will encourage the inference engine more strongly.

    0 讨论(0)
  • 2020-12-17 06:46

    Is there some particular reason why the Kleene star GADT won't do this job?

    data Star r a b where
      Nil   :: Star r a a
      Cons  :: r a b -> Star r b c -> Star r a c
    
    compose :: Star (->) a b -> a -> b
    compose Nil          = id
    compose (Cons f fs)  = compose fs . f
    

    But if you need a type class approach, I wouldn't interfere.

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