{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
-- | Measuring the complexity of type class declarations
module Language.Haskell.Homplexity.TypeClassComplexity
  ( NonTypeDeclCount
  , nonTypeDeclCountT
  , AssocTypeCount
  , assocTypeCountT
  ) where

import           Data.Data
import           Data.Generics.Uniplate.Data              ()
import           Data.Maybe
--import Language.Haskell.Exts.SrcLoc
import           Language.Haskell.Exts.Syntax
import           Language.Haskell.Homplexity.CodeFragment
import           Language.Haskell.Homplexity.Metric
import           Language.Haskell.Homplexity.Utilities

-- NOTE: It is non-trivial to decide whether a class declaration
-- is a method or a value. To correctly do that, we would have to
-- see through type synonyms. So, we will aggregate methods and values.

-- * Type class method count
-- | Represents the number of methods and value in a type class.
newtype NonTypeDeclCount = NonTypeDeclCount { NonTypeDeclCount -> Int
unNonTypeDeclCount :: Int }
  deriving (NonTypeDeclCount -> NonTypeDeclCount -> Bool
(NonTypeDeclCount -> NonTypeDeclCount -> Bool)
-> (NonTypeDeclCount -> NonTypeDeclCount -> Bool)
-> Eq NonTypeDeclCount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
== :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
$c/= :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
/= :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
Eq, Eq NonTypeDeclCount
Eq NonTypeDeclCount
-> (NonTypeDeclCount -> NonTypeDeclCount -> Ordering)
-> (NonTypeDeclCount -> NonTypeDeclCount -> Bool)
-> (NonTypeDeclCount -> NonTypeDeclCount -> Bool)
-> (NonTypeDeclCount -> NonTypeDeclCount -> Bool)
-> (NonTypeDeclCount -> NonTypeDeclCount -> Bool)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> Ord NonTypeDeclCount
NonTypeDeclCount -> NonTypeDeclCount -> Bool
NonTypeDeclCount -> NonTypeDeclCount -> Ordering
NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: NonTypeDeclCount -> NonTypeDeclCount -> Ordering
compare :: NonTypeDeclCount -> NonTypeDeclCount -> Ordering
$c< :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
< :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
$c<= :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
<= :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
$c> :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
> :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
$c>= :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
>= :: NonTypeDeclCount -> NonTypeDeclCount -> Bool
$cmax :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
max :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$cmin :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
min :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
Ord, Int -> NonTypeDeclCount
NonTypeDeclCount -> Int
NonTypeDeclCount -> [NonTypeDeclCount]
NonTypeDeclCount -> NonTypeDeclCount
NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
NonTypeDeclCount
-> NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
(NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount)
-> (Int -> NonTypeDeclCount)
-> (NonTypeDeclCount -> Int)
-> (NonTypeDeclCount -> [NonTypeDeclCount])
-> (NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount])
-> (NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount])
-> (NonTypeDeclCount
    -> NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount])
-> Enum NonTypeDeclCount
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: NonTypeDeclCount -> NonTypeDeclCount
succ :: NonTypeDeclCount -> NonTypeDeclCount
$cpred :: NonTypeDeclCount -> NonTypeDeclCount
pred :: NonTypeDeclCount -> NonTypeDeclCount
$ctoEnum :: Int -> NonTypeDeclCount
toEnum :: Int -> NonTypeDeclCount
$cfromEnum :: NonTypeDeclCount -> Int
fromEnum :: NonTypeDeclCount -> Int
$cenumFrom :: NonTypeDeclCount -> [NonTypeDeclCount]
enumFrom :: NonTypeDeclCount -> [NonTypeDeclCount]
$cenumFromThen :: NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
enumFromThen :: NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
$cenumFromTo :: NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
enumFromTo :: NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
$cenumFromThenTo :: NonTypeDeclCount
-> NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
enumFromThenTo :: NonTypeDeclCount
-> NonTypeDeclCount -> NonTypeDeclCount -> [NonTypeDeclCount]
Enum, Integer -> NonTypeDeclCount
NonTypeDeclCount -> NonTypeDeclCount
NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
(NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount)
-> (Integer -> NonTypeDeclCount)
-> Num NonTypeDeclCount
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
+ :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$c- :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
- :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$c* :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
* :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$cnegate :: NonTypeDeclCount -> NonTypeDeclCount
negate :: NonTypeDeclCount -> NonTypeDeclCount
$cabs :: NonTypeDeclCount -> NonTypeDeclCount
abs :: NonTypeDeclCount -> NonTypeDeclCount
$csignum :: NonTypeDeclCount -> NonTypeDeclCount
signum :: NonTypeDeclCount -> NonTypeDeclCount
$cfromInteger :: Integer -> NonTypeDeclCount
fromInteger :: Integer -> NonTypeDeclCount
Num, Num NonTypeDeclCount
Ord NonTypeDeclCount
Num NonTypeDeclCount
-> Ord NonTypeDeclCount
-> (NonTypeDeclCount -> Rational)
-> Real NonTypeDeclCount
NonTypeDeclCount -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
$ctoRational :: NonTypeDeclCount -> Rational
toRational :: NonTypeDeclCount -> Rational
Real, Enum NonTypeDeclCount
Real NonTypeDeclCount
Real NonTypeDeclCount
-> Enum NonTypeDeclCount
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount)
-> (NonTypeDeclCount
    -> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount))
-> (NonTypeDeclCount
    -> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount))
-> (NonTypeDeclCount -> Integer)
-> Integral NonTypeDeclCount
NonTypeDeclCount -> Integer
NonTypeDeclCount
-> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount)
NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
quot :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$crem :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
rem :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$cdiv :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
div :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$cmod :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
mod :: NonTypeDeclCount -> NonTypeDeclCount -> NonTypeDeclCount
$cquotRem :: NonTypeDeclCount
-> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount)
quotRem :: NonTypeDeclCount
-> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount)
$cdivMod :: NonTypeDeclCount
-> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount)
divMod :: NonTypeDeclCount
-> NonTypeDeclCount -> (NonTypeDeclCount, NonTypeDeclCount)
$ctoInteger :: NonTypeDeclCount -> Integer
toInteger :: NonTypeDeclCount -> Integer
Integral)

-- | For passing @NonTypeDeclCount@ type as parameter.
nonTypeDeclCountT :: Proxy NonTypeDeclCount
nonTypeDeclCountT :: Proxy NonTypeDeclCount
nonTypeDeclCountT  = Proxy NonTypeDeclCount
forall {k} (t :: k). Proxy t
Proxy

instance Show NonTypeDeclCount where
  showsPrec :: Int -> NonTypeDeclCount -> ShowS
showsPrec Int
_ (NonTypeDeclCount Int
mc) = (String
"method + value count of " String -> ShowS
forall a. [a] -> [a] -> [a]
++)
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows Int
mc

instance Metric NonTypeDeclCount TypeClass where
  measure :: TypeClass -> NonTypeDeclCount
measure = Int -> NonTypeDeclCount
NonTypeDeclCount (Int -> NonTypeDeclCount)
-> (TypeClass -> Int) -> TypeClass -> NonTypeDeclCount
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ClassDecl SrcLoc -> Int) -> [ClassDecl SrcLoc] -> Int
forall a. (a -> Int) -> [a] -> Int
sumOf ClassDecl SrcLoc -> Int
forall l. ClassDecl l -> Int
method ([ClassDecl SrcLoc] -> Int)
-> (TypeClass -> [ClassDecl SrcLoc]) -> TypeClass -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ClassDecl SrcLoc]
-> Maybe [ClassDecl SrcLoc] -> [ClassDecl SrcLoc]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [ClassDecl SrcLoc] -> [ClassDecl SrcLoc])
-> (TypeClass -> Maybe [ClassDecl SrcLoc])
-> TypeClass
-> [ClassDecl SrcLoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeClass -> Maybe [ClassDecl SrcLoc]
tcDecls where

    method :: ClassDecl l -> Int
    method :: forall l. ClassDecl l -> Int
method (ClsDecl l
_ TypeSig{}) = Int
1
    method ClassDecl l
_                     = Int
0

-- * Type class associated types count
-- | Represents the number of associated types in a type class.
-- It includes both associated type and data families.
newtype AssocTypeCount = AssocTypeCount { AssocTypeCount -> Int
unAssocTypeCount :: Int }
  deriving (AssocTypeCount -> AssocTypeCount -> Bool
(AssocTypeCount -> AssocTypeCount -> Bool)
-> (AssocTypeCount -> AssocTypeCount -> Bool) -> Eq AssocTypeCount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AssocTypeCount -> AssocTypeCount -> Bool
== :: AssocTypeCount -> AssocTypeCount -> Bool
$c/= :: AssocTypeCount -> AssocTypeCount -> Bool
/= :: AssocTypeCount -> AssocTypeCount -> Bool
Eq, Eq AssocTypeCount
Eq AssocTypeCount
-> (AssocTypeCount -> AssocTypeCount -> Ordering)
-> (AssocTypeCount -> AssocTypeCount -> Bool)
-> (AssocTypeCount -> AssocTypeCount -> Bool)
-> (AssocTypeCount -> AssocTypeCount -> Bool)
-> (AssocTypeCount -> AssocTypeCount -> Bool)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> Ord AssocTypeCount
AssocTypeCount -> AssocTypeCount -> Bool
AssocTypeCount -> AssocTypeCount -> Ordering
AssocTypeCount -> AssocTypeCount -> AssocTypeCount
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: AssocTypeCount -> AssocTypeCount -> Ordering
compare :: AssocTypeCount -> AssocTypeCount -> Ordering
$c< :: AssocTypeCount -> AssocTypeCount -> Bool
< :: AssocTypeCount -> AssocTypeCount -> Bool
$c<= :: AssocTypeCount -> AssocTypeCount -> Bool
<= :: AssocTypeCount -> AssocTypeCount -> Bool
$c> :: AssocTypeCount -> AssocTypeCount -> Bool
> :: AssocTypeCount -> AssocTypeCount -> Bool
$c>= :: AssocTypeCount -> AssocTypeCount -> Bool
>= :: AssocTypeCount -> AssocTypeCount -> Bool
$cmax :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
max :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$cmin :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
min :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
Ord, Int -> AssocTypeCount
AssocTypeCount -> Int
AssocTypeCount -> [AssocTypeCount]
AssocTypeCount -> AssocTypeCount
AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
AssocTypeCount
-> AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
(AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount)
-> (Int -> AssocTypeCount)
-> (AssocTypeCount -> Int)
-> (AssocTypeCount -> [AssocTypeCount])
-> (AssocTypeCount -> AssocTypeCount -> [AssocTypeCount])
-> (AssocTypeCount -> AssocTypeCount -> [AssocTypeCount])
-> (AssocTypeCount
    -> AssocTypeCount -> AssocTypeCount -> [AssocTypeCount])
-> Enum AssocTypeCount
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: AssocTypeCount -> AssocTypeCount
succ :: AssocTypeCount -> AssocTypeCount
$cpred :: AssocTypeCount -> AssocTypeCount
pred :: AssocTypeCount -> AssocTypeCount
$ctoEnum :: Int -> AssocTypeCount
toEnum :: Int -> AssocTypeCount
$cfromEnum :: AssocTypeCount -> Int
fromEnum :: AssocTypeCount -> Int
$cenumFrom :: AssocTypeCount -> [AssocTypeCount]
enumFrom :: AssocTypeCount -> [AssocTypeCount]
$cenumFromThen :: AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
enumFromThen :: AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
$cenumFromTo :: AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
enumFromTo :: AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
$cenumFromThenTo :: AssocTypeCount
-> AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
enumFromThenTo :: AssocTypeCount
-> AssocTypeCount -> AssocTypeCount -> [AssocTypeCount]
Enum, Integer -> AssocTypeCount
AssocTypeCount -> AssocTypeCount
AssocTypeCount -> AssocTypeCount -> AssocTypeCount
(AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount)
-> (Integer -> AssocTypeCount)
-> Num AssocTypeCount
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
+ :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$c- :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
- :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$c* :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
* :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$cnegate :: AssocTypeCount -> AssocTypeCount
negate :: AssocTypeCount -> AssocTypeCount
$cabs :: AssocTypeCount -> AssocTypeCount
abs :: AssocTypeCount -> AssocTypeCount
$csignum :: AssocTypeCount -> AssocTypeCount
signum :: AssocTypeCount -> AssocTypeCount
$cfromInteger :: Integer -> AssocTypeCount
fromInteger :: Integer -> AssocTypeCount
Num, Num AssocTypeCount
Ord AssocTypeCount
Num AssocTypeCount
-> Ord AssocTypeCount
-> (AssocTypeCount -> Rational)
-> Real AssocTypeCount
AssocTypeCount -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
$ctoRational :: AssocTypeCount -> Rational
toRational :: AssocTypeCount -> Rational
Real, Enum AssocTypeCount
Real AssocTypeCount
Real AssocTypeCount
-> Enum AssocTypeCount
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount -> AssocTypeCount -> AssocTypeCount)
-> (AssocTypeCount
    -> AssocTypeCount -> (AssocTypeCount, AssocTypeCount))
-> (AssocTypeCount
    -> AssocTypeCount -> (AssocTypeCount, AssocTypeCount))
-> (AssocTypeCount -> Integer)
-> Integral AssocTypeCount
AssocTypeCount -> Integer
AssocTypeCount
-> AssocTypeCount -> (AssocTypeCount, AssocTypeCount)
AssocTypeCount -> AssocTypeCount -> AssocTypeCount
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
quot :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$crem :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
rem :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$cdiv :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
div :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$cmod :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
mod :: AssocTypeCount -> AssocTypeCount -> AssocTypeCount
$cquotRem :: AssocTypeCount
-> AssocTypeCount -> (AssocTypeCount, AssocTypeCount)
quotRem :: AssocTypeCount
-> AssocTypeCount -> (AssocTypeCount, AssocTypeCount)
$cdivMod :: AssocTypeCount
-> AssocTypeCount -> (AssocTypeCount, AssocTypeCount)
divMod :: AssocTypeCount
-> AssocTypeCount -> (AssocTypeCount, AssocTypeCount)
$ctoInteger :: AssocTypeCount -> Integer
toInteger :: AssocTypeCount -> Integer
Integral)

-- | For passing @AssocTypeCount@ type as parameter.
assocTypeCountT :: Proxy AssocTypeCount
assocTypeCountT :: Proxy AssocTypeCount
assocTypeCountT  = Proxy AssocTypeCount
forall {k} (t :: k). Proxy t
Proxy

instance Show AssocTypeCount where
  showsPrec :: Int -> AssocTypeCount -> ShowS
showsPrec Int
_ (AssocTypeCount Int
atc) = (String
"associated type count of " String -> ShowS
forall a. [a] -> [a] -> [a]
++)
                                   ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows Int
atc

instance Metric AssocTypeCount TypeClass where
  measure :: TypeClass -> AssocTypeCount
measure = Int -> AssocTypeCount
AssocTypeCount (Int -> AssocTypeCount)
-> (TypeClass -> Int) -> TypeClass -> AssocTypeCount
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ClassDecl SrcLoc -> Int) -> [ClassDecl SrcLoc] -> Int
forall a. (a -> Int) -> [a] -> Int
sumOf ClassDecl SrcLoc -> Int
forall l. ClassDecl l -> Int
assocType ([ClassDecl SrcLoc] -> Int)
-> (TypeClass -> [ClassDecl SrcLoc]) -> TypeClass -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ClassDecl SrcLoc]
-> Maybe [ClassDecl SrcLoc] -> [ClassDecl SrcLoc]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [ClassDecl SrcLoc] -> [ClassDecl SrcLoc])
-> (TypeClass -> Maybe [ClassDecl SrcLoc])
-> TypeClass
-> [ClassDecl SrcLoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeClass -> Maybe [ClassDecl SrcLoc]
tcDecls where

    assocType :: ClassDecl l -> Int
    assocType :: forall l. ClassDecl l -> Int
assocType ClsTyFam{}   = Int
1
    assocType ClsTyDef{}   = Int
1
    assocType ClsDataFam{} = Int
1
    assocType ClassDecl l
_            = Int
0