Let them carefully compare types hashFilewith types categorize, bearing in mind that we want to pass hashFileas an argument tocategorize
hashFile :: FilePath -> IO (Digest MD5) -- I simplified the MonadIO constraint
categorize :: Ord k => ( a -> k ) -> [a] -> M.Map k [a]
categorize hashFile , GHC k IO (Digest MD5), IO Ord. , IO (Digest MD5) Map: Digest MD5 s, , Digest MD5 .
, IO ( Digest MD5) Map. IO (Map (Digest MD5) FilePath) - an IO , a Map (Digest MD5) FilePath .
- categorize , .
categorize :: (Applicative f, Ord k) => (a -> f k) -> [a] -> f (M.Map k a)
categorize f = fmap M.fromList . traverse (\x -> fmap (, x) (f x))
( TupleSections.) . IO Applicative, (a -> f k) FilePath -> IO (Digest MD5) :
a ~ FilePath
f ~ IO
k ~ Digest MD5
categorize hashFile :: [FilePath] -> IO (M.Map (Digest MD5) FilePath), .
. traverse :: Applicative f => (a -> f b) -> [a] -> f [b] * (née mapM) Applicative, . (result, item). f [(k, a)]. fmap M.fromList , f (M.Map k a).
* , traverse (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b). , t ~ [].
M.fromList, . , , , MD5 , . : , ?