Lis*_*one 4 haskell list traversable
我有以下实现目录漫游的模块:
module Walk
( walk
) where
import Control.Monad
import Control.Monad.IO.Class
import Data.List
import System.Directory
import System.FilePath
walk :: (MonadIO m) => FilePath -> m [(FilePath, [FilePath])]
walk root = do
entries <- liftIO $ listDirectory root
(files, dirs) <- partition snd <$> liftM2 (<$>) zip (mapM (liftIO . doesFileExist . (root </>))) entries
((root, map fst files) :) . concat <$> mapM (walk . (root </>) . fst) dirs
Run Code Online (Sandbox Code Playgroud)
它当前返回一个列表,但我希望它返回一个Traversable:
walk :: (MonadIO m, Traversable t) => FilePath -> m (t (FilePath, [FilePath]))
Run Code Online (Sandbox Code Playgroud)
如果更改签名,则会出现以下错误:
• Couldn't match type ‘t’ with ‘[]’
‘t’ is a rigid type variable bound by
the type signature for:
walk :: forall (m :: * -> *) (t :: * -> *).
(MonadIO m, Traversable t) =>
FilePath -> m (t (FilePath, [FilePath]))
Expected type: m (t (FilePath, [FilePath]))
Actual type: m [(FilePath, [FilePath])]
• In a stmt of a 'do' block:
((root, map fst files) :) . concat
<$> mapM (walk . (root </>) . fst) dirs
In the expression:
do entries <- liftIO $ listDirectory root
(files, dirs) <- partition snd
<$>
liftM2
(<$>) zip (mapM (liftIO . doesFileExist .
(root </>))) entries
((root, map fst files) :) . concat
<$> mapM (walk . (root </>) . fst) dirs
In an equation for ‘walk’:
walk root
= do entries <- liftIO $ listDirectory root
(files, dirs) <- partition snd
<$>
liftM2
(<$>)
zip
(mapM (liftIO . doesFileExist .
(root </>)))
entries
((root, map fst files) :) . concat
<$> mapM (walk . (root </>) . fst) dirs
• Relevant bindings include
walk :: FilePath -> m (t (FilePath, [FilePath]))
Run Code Online (Sandbox Code Playgroud)
我认为它失败了:吗?我不能确定 我该如何解决?
我认为它失败了
:吗?
它的确是。如果(:)用于构建结构,则该结构将是一个列表,并且不能更改其类型walk以声明其返回任意可遍历的结构。也没有真正以中心为Traversable中心的解决方法:Traversable意味着您通过其Foldable超类拥有a toList,但没有a fromList。