Search code examples
haskelltypeclass

Why doesn't DefaultSignatures allow concrete types?


{-# LANGUAGE DefaultSignatures #-}
class C a where
  f :: [a]
  default f :: (Num a) => [a]
  f = [1,2,3,4,5]

The above works, the below doesn't. It seems DefaultSignatures extension only allows specifying constraints, but not substituting a concrete type. Section Default Method Signatures of the GHC Users Guide doesn't explain this. Why doesn't DefaultSignatures allow me to substitute a concrete type? What is the rationale? Where can I read more on how and why DefaultSignatures are implemented?

{-# LANGUAGE DefaultSignatures #-}
class C a where
  f :: [a]
  default f :: [Int]
  f = [1,2,3,4,5]

Solution

  • If you're using GHC 8.0.2 then you should write it in different way because there was type checker regression for those kinds of types. See notes:

    https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/8.0.2-notes.html

    So you need to write it like this:

    {-# LANGUAGE DefaultSignatures #-}
    {-# LANGUAGE TypeFamilies #-}
    
    class C a where
      f :: [a]
      default f :: (a ~ Int) => [a]
      f = [1,2,3,4,5]
    

    Instead of saying that f has type of list of Ints, you need to say, that f has type of lists of some type a where a is Int. {-# LANGUAGE TypeFamilies #-} language extension is needed to enable type equalities. It's not what it's used for but it is required. Compiles for GHC 8.0.2