Which dictionary does GHC choose when more than one is in scope?

后端 未结 3 1179
臣服心动
臣服心动 2021-01-11 16:51

Consider the following example:

import Data.Constraint

class Bar a where
  bar :: a -> a

foo :: (Bar a) => Dict (Bar a) -> a -> a
foo Dict = ba         


        
3条回答
  •  南笙
    南笙 (楼主)
    2021-01-11 17:31

    It just picks one. This isn't the correct choice; it's a pretty well-known wart. You can cause crashes this way, so it's a pretty bad state of affairs. Here is a short example using nothing but GADTs that demonstrates that it is possible to have two different instances in scope at once:

    -- file Class.hs
    {-# LANGUAGE GADTs #-}
    module Class where
    
    data Dict a where
      Dict :: C a => Dict a
    
    class C a where
      test :: a -> Bool
    
    -- file A.hs
    module A where
    
    import Class
    
    instance C Int where
      test _ = True
    
    v :: Dict Int
    v = Dict
    
    -- file B.hs
    module B where
    
    import Class
    
    instance C Int where
      test _ = False
    
    f :: Dict Int -> Bool
    f Dict = test (0 :: Int)
    
    -- file Main.hs
    import TestA
    import TestB
    
    main = print (f v)
    

    You will find that Main.hs compiles just fine, and even runs. It prints True on my machine with GHC 7.10.1, but that's not a stable outcome. Turning this into a crash is left to the reader.

提交回复
热议问题