Last active
September 26, 2019 09:55
-
-
Save safareli/e04a277d5662490b4d37bb0c0412b05f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data Count = One | Two | ThreeOrMore | |
type Datum = { count :: Count, char :: Char } | |
data Stat = Stat (Array Datum) | |
instance semigroupCount :: Semigroup Count where | |
append One One = Two | |
append One _ = ThreeOrMore | |
append Two _ = ThreeOrMore | |
toStat :: Char -> Stat | |
toStat = Stat [{ count: One, char: _ }] | |
fromDatum :: Datum -> [Char] | |
fromDatum {count, char} = case count of | |
One -> [char] | |
Two -> [char, char] | |
ThreeOrMore -> [] | |
instance semigroupStat :: Semigroup Stat where | |
append (Stat a) (Stat b) = case Array.unsnoc a of | |
Nothing -> Stat b -- a is empty | |
Just { init, last } -> case Array.uncons b of | |
Nothing -> Stat a -- b is empty | |
Just { head, tail } | |
| last.char == head.char -> | |
let count = append last.count head.count | |
in if count == ThreeOrMore | |
then append (Stat init) (Stat tail) -- recursive call | |
else (Stat (init <> [{ count, char: head.char }] <> tail) | |
| otherwise -> Stat (append a b) | |
instance monoidStat :: Monoid Stat where | |
mempty = Stat [] | |
compute :: [Char] -> [Char] | |
compute = foldMap toDatum >>> un Stat >>> foldMap fromDatum | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment