
Martin,
importFile :: Editor -> String -> IO () importFile ed path = do s <- readFile path ps <- mapM (\x -> makePair (x, "")) (lines s) es <- return $ V.fromList ps writeIORef ed es
loadFile :: Editor -> String -> IO () loadFile ed path = do s <- readFile path ps <- mapM makePair (parseFile s) es <- return $ V.fromList ps writeIORef ed es
The problem is that loadFile and importFile are so similar it seems a shame not to combine them somehow, but anything I can think of doing leaves the code looking more rather than less messy. Any nice ideas?
Have you considered abstracting over the bits in which importFile and loadFile differ? For example: processFile :: (String -> IO [PairBox]) -> Editor -> String -> IO () processFile f ed path = do s <- readFile path ps <- f s es <- return $ V.fromList ps writeIORef ed es importFile = processFile (mapM (\x -> makePair (x, "")) . lines) loadFile = processFile (mapM makePair . parseFile) Or, alternatively: processFile :: (String -> [a]) -> (a -> IO PairBox) -> Editor -> String -> IO () processFile f g ed path = do s <- readFile path ps -> mapM g (f s) es -> return $ V.fromList ps writeIORef ed es importFile = processFile lines (\x -> makePair (x, "")) loadFile = processFile parseFile makePair Or: processFile :: (String -> [a]) -> (a -> (String, String)) -> Editor -> String -> IO () processFile f g ed path = do s <- readFile path ps -> mapM (makePair . g) (f s) es -> return $ V.fromList ps writeIORef ed es importFile = processFile lines (flip (,) "") loadFile = processFile parseFile id HTH, Stefan