mid3 :: Int -> Either String String
mid3 n
  | m < 100 = Left "is too small"
  | even lng = Left "has an even number of digits"
  | otherwise = Right . take 3 $ drop ((lng - 3) `div` 2) s
  where
    m = abs n
    s = show m
    lng = length s


main :: IO ()
main = do
  let xs =
        [ 123
        , 12345
        , 1234567
        , 987654321
        , 10001
        , -10001
        , -123
        , -100
        , 100
        , -12345
        , 1
        , 2
        , -1
        , -10
        , 2002
        , -2002
        , 0
        ]
      w = maximum $ (length . show) <$> xs
  (putStrLn . unlines) $
    (\n ->
        justifyRight w ' ' (show n) ++
        " -> " ++ either ((>>= id) . ("(":) . (: [")"])) id (mid3 n)) <$>
    xs
  where
    justifyRight :: Int -> Char -> String -> String
    justifyRight n c s = drop (length s) (replicate n c ++ s)