How to create a monad function and action in Haskell

I just started to learn Haskell.

I am creating a program that finds duplicate files. I created the following functions:

hashFile :: (MonadIO m) => FilePath -> m (Digest MD5)
categorize :: Ord k => (a -> k) -> [a] -> Map.Map k [a]

And I want to compose them into a function that returns

Map.Map (Digest MD5) [FilePath]

My questions:

I cannot find a way to deal with the IO monad to get what I want. So my questions are:

  • I'm trying to do it right, or if the return type will really be Map.Map (IO (Digest MD5)) [FilePath].

  • How do I put these functions together to get a list of files grouped by a hash?

+4
source share
1 answer

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 , . : , ?

+6

All Articles