checksum :: String -> String
checksum input
    | null input = error "can't calc checksum of empty str"
    | odd (length input) = error "can't calc checksum of odd length str"
    | otherwise = until (odd . length) cs input
  where
    cs str = seq' (reverse $ cs' "" str)
    cs' memo (c0:c1:t) = cs' (seq' nextMemo) t
      where
        nextChar = if c0 == c1 then '1' else '0'
        nextMemo = nextChar : memo
    cs' memo [] = memo
checksum :: String -> String
checksum input
    | null input = error "can't calc checksum of empty str"
    | odd (length input) = error "can't calc checksum of odd length str"
    | otherwise = until (odd . length) cs input
  where
    cs str = seq' (reverse $ cs' "" str)
    cs' memo (c0:c1:t) = cs' (seq' nextMemo) t
      where
        nextChar = if c0 == c1 then '1' else '0'
        nextMemo = nextChar : memo
    cs' memo [] = memo
checksum input
    | null input = error "can't calc checksum of empty str"
    | odd (length input) = error "can't calc checksum of odd length str"
    | otherwise = until (odd . length) cs input
  where
    cs str = seq' (reverse $ cs' "" str)
    cs' memo (c0:c1:t) = cs' (seq' nextMemo) t
      where
        nextChar = if c0 == c1 then '1' else '0'
        nextMemo = nextChar : memo
    cs' memo [] = memo