refactor based on ghc base source