user855443
user855443

Reputation: 2948

Deriving a class with a single constant

I would like to derive a class with a constant and some trivial operations:

class  Zeros z where
    zero :: z
    isZero  :: Eq z =>  z -> Bool
    isZero z = zero == z

and in another module:

{-# LANGUAGE DeriveGeneric, DeriveAnyClass
    , GeneralizedNewtypeDeriving #-}
module Lib.DerivingExampleDerive
    where
import Data.Text
import Lib.DerivingExample
import GHC.Generics

newtype Basis1 = Basis1 Text deriving (Show, Read, Eq, Ord, Generic, Zeros)

GHC 8.2.2 produces the error:

/home/frank/Workspace8/testSome/Lib/DerivingExampleDerive.hs:26:70: warning:
    • Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled
      Defaulting to the DeriveAnyClass strategy for instantiating Zeros
    • In the newtype declaration for ‘Basis1’
   |         
26 | newtype Basis1 = Basis1 Text deriving (Show, Read, Eq, Ord, Generic, Zeros)
   |                                                                      ^^^^^

/home/frank/Workspace8/testSome/Lib/DerivingExampleDerive.hs:26:70: warning: [-Wmissing-methods]
    • No explicit implementation for
        ‘zero’
    • In the instance declaration for ‘Zeros Basis1’
   |         
26 | newtype Basis1 = Basis1 Text deriving (Show, Read, Eq, Ord, Generic, Zeros)
   |                                                                      ^^^^^

I understand the first message (considering Ryan Scott's blog post on deriving strategies but not the second.

Should I conclude that the deriving mechanism in Haskell cannot derive constants? I have given

instance Zeros Text where zero = (""::Text)

and the derivation for

instance Zeros Basis1 where zero = Basis1 zero  

should be resulting from the strategy of DeriveAnyClass but is not.

Upvotes: 0

Views: 215

Answers (2)

dfeuer
dfeuer

Reputation: 48631

You pointed to Ryan's blog post that explains a fix. Why don't you use it? Add DerivingStrategies and then use deriving newtype Zeros.

Upvotes: 2

Daniel Wagner
Daniel Wagner

Reputation: 153182

GeneralizedNewtypeDeriving will write the instance you propose, but DeriveAnyClass will write this instance:

instance Zeros Text => Zeros Basis1

N.B. there are no method definitions! For that to work, you need to give a default implementation for every method; usually this is done with generics or a similar generic programming toolkit.

Upvotes: 3

Related Questions