gpt4 book ai didi

haskell - 如何在 Haskell 中组合函数和 monad Action

转载 作者:行者123 更新时间:2023-12-05 00:18:46 24 4
gpt4 key购买 nike

我刚刚开始学习 Haskell。

我正在创建一个查找重复文件的程序。我创建了以下功能:

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

我想将它们组合在一个返回的函数中
Map.Map (Digest MD5) [FilePath]

我的问题是:

我找不到处理 IO monad 的方法来获得我想要的东西。所以我的问题是:
  • 我正在尝试做的事情是正确的,还是应该返回类型
    真的是Map.Map (IO (Digest MD5)) [FilePath] .
  • 如何将这些函数组合在一起以获取按哈希分组的文件列表?
  • 最佳答案

    让我们仔细比较hashFile的类型类型为 categorize ,记住我们要通过hashFile作为 categorize 的参数

    hashFile ::             FilePath -> IO (Digest MD5)  -- I simplified the MonadIO constraint
    categorize :: Ord k => ( a -> k ) -> [a] -> M.Map k [a]
    categorize hashFile不会进行类型检查,因为 GHC 会尝试匹配 kIO (Digest MD5) ,但是 IO没有 Ord实例。换句话说, IO (Digest MD5)作为 Map 的 key 没用: 你需要的是 Digest MD5 s,而不是最终会产生 Digest MD5 的计算s 执行它们时。

    你真正想做的是运行所有 IO计算并将其结果(类型 Digest MD5)放入 Map .结果函数将返回 IO (Map (Digest MD5) FilePath) - 一个 IO计算将返回 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 。)首先让我们看一下类型。自 IOApplicative 的一个实例, (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)]值(value)。然后我 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 哈希值会有所不同,因此这不会成为问题。练习:如果我们想保留重复项,这将如何改变?

    关于haskell - 如何在 Haskell 中组合函数和 monad Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37287749/

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