gpt4 book ai didi

haskell - 寻找目录内容大小时的 IO 问题?

转载 作者:行者123 更新时间:2023-12-04 18:29:23 24 4
gpt4 key购买 nike

我正在学习 Haskell,我今天的目标是写一个函数 sizeOf :: FilePath -> IO Integer (计算文件或文件夹的大小),逻辑

  • path是一个文件,System.Directory.getFileSize path
  • path是一个目录,获取其内容列表,对它们递归运行此函数,然后 sum结果
  • 如果不是文件或目录,return 0

  • 下面是我如何在 Ruby 中实现它,以说明(Ruby 注释: map 的参数等效于 \d -> size_of dreduce :+foldl (+) 0 ,任何以 ? 结尾的函数都返回一个 bool 值,返回的是隐式):
    def size_of path
    if File.file? path
    File.size path
    elsif File.directory? path
    Dir.glob(path + '/*').map { |d| size_of d }.reduce :+
    end
    end

    这是我在 Haskell 中的破解:
      sizeOf :: FilePath -> IO Integer
    sizeOf path =
    do
    isFile <- doesFileExist path
    if isFile then
    getFileSize path
    else do
    isDir <- doesDirectoryExist path
    if isDir then
    sum $ map sizeOf $ listDirectory path
    else
    return 0

    我知道我的问题在哪里。 sum $ map sizeOf $ listDirectory path ,其中 listDirectory path返回 IO [FilePath]而不是 FilePath .但是......我真的无法想象任何解决方案来解决这个问题。 <$>而不是 $是我想到的第一件事,因为 <$>我明白是让 a -> b 的函数的东西成为 Context a -> Context b .但是……我猜IO不是那样的?

    我花了大约两个小时对那里的逻辑感到困惑。我在其他示例上尝试过。这是一个相关的发现,让我感到震惊:如果 double = (*) 2 ,然后 map double [1,2,3] == [2,4,6] ,但是 map double <$> [return 1, return 2, return 3] == [[2],[4],[6]] ...它将它们包装在一个列表中。我认为这就是发生在我身上的事情,但我已经超出了我的深度。

    最佳答案

    你需要

    sum <$> (listDirectory path >>= mapM sizeOf)

    解释:
  • 使用的想法 sum超过 IO [Integer]没关系,所以我们需要得到这样的东西。
  • listDirectory path给我们 IO [FilePath] ,所以我们需要将每个文件路径传递给 sizeOf .这是什么>>=连同mapM做。
  • 请注意 map单独会给我们[IO Integer]这就是为什么我们需要 mapM
  • 关于haskell - 寻找目录内容大小时的 IO 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41312909/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com