{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Language.Haskell.Homplexity.Metric (
Metric (..)
, LOC
, locT
, measureAs
, measureFor
) where
import Data.Data
import Data.Function
import Control.Arrow
import Data.Generics.Uniplate.Data
import Data.List
import Language.Haskell.Exts.SrcLoc
import Language.Haskell.Homplexity.CodeFragment
class (CodeFragment c, Show m) => Metric m c where
measure :: c -> m
newtype LOC = LOC { _asInt :: Int }
deriving (Ord, Eq, Enum, Num, Real, Integral)
locT :: Proxy LOC
locT = Proxy
instance Show LOC where
showsPrec _ (LOC l) = shows l . (" lines of code"++)
instance Read LOC where
readsPrec prec str = first LOC <$> readsPrec prec str
instance (CodeFragment c) => Metric LOC c where
measure = LOC
. length
. concatMap (nub . map srcLine)
. groupBy ((==) `on` srcFilename)
. universeBi
measureAs :: (Metric m c) => Proxy m -> c -> m
measureAs _ = measure
measureFor :: (Metric m c) => Proxy m -> Proxy c -> c -> m
measureFor _ _ = measure