module ELynx.Data.Sequence.Distance
( hamming,
)
where
import qualified Data.Vector.Unboxed as V
import ELynx.Data.Sequence.Sequence
countFalses :: (Int -> Bool -> Int)
countFalses n False = succ n
countFalses n True = n
hamming :: Sequence -> Sequence -> Either String Int
hamming l r
| alphabet l /= alphabet r = Left "hamming: Alphabets of sequences differ."
| V.length csL /= V.length csR = Left "hamming: Sequence lengths differ."
| V.null csL || V.null csR = Left "hamming: Empty sequence encountered."
| otherwise = Right $ V.foldl' countFalses 0 $ V.zipWith (==) (characters l) (characters r)
where
csL = characters l
csR = characters r