This is a bit difficult to explain, but I've run into this situation a few times.
The code is as follows:
work :: String -> IO ()
work a = do
input <- lines <$> getContents
sortF <- let f = flip sortByM input
in case a of
"name" -> f (return . id :: FilePath -> IO FilePath)
"time" -> f (getModificationTime :: FilePath -> IO UTCTime)
_ -> f (getModificationTime :: FilePath -> IO UTCTime)
print sortF
sortByM :: (Monad m, Ord a) => (b-> m a) -> [b] -> m [b]
sortByM f x = do
x' <- mapM f x
return $ fst <$> (sortBy (comparing snd) $ zip x x')
The above throws an error of:
• Couldn't match type ‘UTCTime’ with ‘[Char]’
Expected type: String -> IO FilePath
Actual type: FilePath -> IO UTCTime
• In the first argument of ‘f’, namely
‘(getModificationTime :: FilePath -> IO UTCTime)’
In the expression:
f (getModificationTime :: FilePath -> IO UTCTime)
In a case alternative:
"time" -> f (getModificationTime :: FilePath -> IO UTCTime)
Which makes sense, but is there a way to somehow achieve the above? Otherwise I have to do the below, which feels less maintainable:
work :: String -> IO ()
work a = do
input <- lines <$> getContents
sortF <- case a of
"name" -> flip sortByM input (return . id :: FilePath -> IO FilePath)
"time" -> flip sortByM input (getModificationTime :: FilePath -> IO UTCTime)
_ -> flip sortByM input (getModificationTime :: FilePath -> IO UTCTime)
print sortF
sortByM :: (Monad m, Ord a) => (b-> m a) -> [b] -> m [b]
sortByM f x = do
x' <- mapM f x
return $ fst <$> (sortBy (comparing snd) $ zip x x')