gpt4 book ai didi

haskell - 在 Haskell 中处理嵌套 IO 的惯用方法

转载 作者:行者123 更新时间:2023-12-02 06:43:40 25 4
gpt4 key购买 nike

我正在学习 Haskell,并编写一个简短的解析脚本作为练习。我的大部分脚本由纯函数组成,但我有两个嵌套的 IO 组件:

  1. 从路径读取文件列表。
  2. 读取每个文件的内容,这反过来将成为程序其余大部分部分的输入。

我所做的工作,但是嵌套 IO 和 fmap 层“感觉”笨重,就像我应该避免嵌套 IO (以某种方式),或者更熟练地使用 do 表示法来避免所有 fmap。我想知道我是否使事情过于复杂,做错了等等。这是一些相关代码:

getPaths :: FilePath -> IO [String]
getPaths folder = do
allFiles <- listDirectory folder
let txtFiles = filter (isInfixOf ".txt") allFiles
paths = map ((folder ++ "/") ++) txtFiles
return paths

getConfig :: FilePath -> IO [String]
getConfig path = do
config <- readFile path
return $ lines config

main = do
paths = getPaths "./configs"
let flatConfigs = map getConfigs paths
blockConfigs = map (fmap chunk) flatConfigs
-- Parse and do stuff with config data.
return

我最终通过使用listDirectory作为readFile的输入来处理IO [IO String]。并非难以管理,但如果我使用 do 表示法来解开 [IO String] 以发送到某些解析器函数,我最终仍然会使用嵌套的 fmap 或污染我所谓的纯粹具有 IO 感知功能(fmap 等)。后者似乎更糟糕,所以我正在做前者。示例:

type Block = [String]
getTrunkBlocks :: [Block] -> [Block]
getTrunkBlocks = filter (liftM2 (&&) isInterface isMatchingInt)
where isMatchingInt line = isJust $ find predicate line
predicate = isInfixOf "switchport mode trunk"

main = do
paths <- getPaths "./configs"
let flatConfigs = map getConfig paths
blockConfigs = map (fmap chunk) flatConfigs
trunks = fmap (fmap getTrunkBlocks) blockConfigs
return $ "Trunk count: " ++ show (length trunks)

fmap,fmap,fmap...我觉得我无意中让这个变得比必要的更加复杂,并且无法想象如果我有更深的 IO 嵌套,这会变得多么复杂。

建议?

提前致谢。

最佳答案

我想你的main想要这样的东西:

main = do
paths <- getPaths "./configs"
flatConfigs <- traverse getConfig paths
let blockConfigs = fmap chunk flatConfigs
-- Parse and do stuff with config data.
return ()

比较

fmap :: Functor f => (a -> b) -> f a -> f b

traverse :: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)

它们非常相似,但是 traverse 允许您使用 IO 等效果。

下面是一些专门用于比较的类型:

fmap     :: (a -> b)    -> [a] -> [b]
traverse :: (a -> IO b) -> [a] -> IO [b]

(traverse 也称为 mapM)

关于haskell - 在 Haskell 中处理嵌套 IO 的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42567416/

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