Can GHC warn if class instance is a loop?

后端 未结 5 1657
长情又很酷
长情又很酷 2021-01-17 11:54

Real World Haskell has this example:

class BasicEq3 a where
    isEqual3 :: a -> a -> Bool
    isEqual3 x y = not (isNotEqual3 x y)

    isNotEqual3 ::         


        
5条回答
  •  庸人自扰
    2021-01-17 12:25

    In my personal opinion, the defaulting mechanism is unnecessary and unwise. It would be easy for the class author to just provide the defaults as ordinary functions:

    notEq3FromEq3 :: (a -> a -> Bool) -> (a -> a -> Bool)
    notEq3FromEq3 eq3 = (\x y -> not (eq3 x y))
    
    eq3FromNotEq3 :: (a -> a -> Bool) -> (a -> a -> Bool)
    eq3FromNotEq3 ne3 = (\x y -> not (ne3 x y))
    

    (In fact, these two definitions are equal, but that would not be true in general). Then an instance looks like:

     instance BasicEq3 Bool where
       isEqual3 True True = True
       isEqual3 False False = True
       isEqual3 _ _ = False
    
       isNotEqual3 = notEq3FromEq3 isEqual3
    

    and no defaults are required. Then GHC can warn you if you don't provide the definition, and any unpleasant loops have to be explicitly written by you into your code.

    This does remove the neat ability to add new methods to a class with default definitions without affecting existing instances, but that's not so huge a benefit in my view. The above approach is also in principle more flexible: you could e.g. provide functions that allowed an Ord instance to choose any comparison operator to implement.

提交回复
热议问题