Can GHC warn if class instance is a loop?

后端 未结 5 1683
长情又很酷
长情又很酷 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:26

    No, there isn't, since if the compiler could make this determination, that would be equivalent to solving the Halting Problem. In general, the fact that two functions call each other in a "loop" pattern is not enough to conclude that actually calling one of the functions will result in a loop.

    To use a (contrived) example,

    collatzOdd :: Int -> Int
    collatzOdd 1 = 1
    collatzOdd n = let n' = 3*n+1 in if n' `mod` 2 == 0 then collatzEven n'
                                       else collatzOdd n'
    
    collatzEven :: Int -> Int
    collatzEven n = let n' = n `div` 2 in if n' `mod` 2 == 0 then collatzEven n'
                                            else collatzOdd n'
    
    collatz :: Int -> Int
    collatz n = if n `mod` 2 == 0 then collatzEven n else collatzOdd n
    

    (This is of course not the most natural way to implement the Collatz conjecture, but it illustrates mutually recursive functions.)

    Now collatzEven and collatzOdd depend on each other, but the Collatz conjecture states that calling collatz terminates for all positive n. If GHC could determine whether a class that had collatzOdd and collatzEven as default definitions had a complete definition or not, then GHC would be able to solve the Collatz conjecture! (This is of course not a proof of the undecideability of the Halting Problem, but it should illustrate why determining whether a mutually recursive set of functions is well-defined is not at all as trivial as it may seem.)

    In general, since GHC cannot determine this automatically, documentation for Haskell classes will give the "minimal complete definition" necessary for creating an instance of a class.

提交回复
热议问题