Haskell 将需要IO的函数映射到列表的更好方法
所以最近我有一个字符串列表,需要独立地检查每个字符串并执行一些Haskell 将需要IO的函数映射到列表的更好方法,haskell,Haskell,所以最近我有一个字符串列表,需要独立地检查每个字符串并执行一些IO函数 所以基本上我得到的是: goOverList :: [String] -> IO () goOverList (x:[]) = do putStrLn x goOverList (x:xs) = do goOverList [x] goOverList xs main = do let myList = ["first", "second", "third"] goOverLi
IO
函数
所以基本上我得到的是:
goOverList :: [String] -> IO ()
goOverList (x:[]) = do
putStrLn x
goOverList (x:xs) = do
goOverList [x]
goOverList xs
main = do
let myList = ["first", "second", "third"]
goOverList myList
我的
IO
有点复杂,但这就是它的要点(需要一个函数遍历列表并根据列表成员执行IO
),我希望有人能告诉我如何做得更好 您的goOverList
函数几乎等同于mapM_uu.putStrLn
。(这几乎是因为mapM
也可以处理空列表,而函数不能)
是一个函数,它将类型为a->IO b
1的函数应用于a
s列表中的每个项目,并返回带有b
s列表的IO
2mapM
与mapM
相同,只是它不将结果存储在列表中(这对于返回()
的操作(如putStrLn
的操作)没有意义
实际上,它比这更一般:函数有类型a->mb
,其中Monad m
,但在这种情况下m
是IO
²实际上也是m.首先,简单的改进:
goOverList' :: [String] -> IO ()
goOverList' [] = return ()
goOverList' (x:xs) = do
putStrLn x
goOverList' xs
递归的基本情况应该是空列表:在这种情况下,您只需返回IO操作return()
,它什么也不做。当您有一个或多个元素时,您可以打印它并继续处理列表的其余部分,就这么简单
同样的事情也可以通过使用mapM\:Monad m=>(a->mb)->[a]->m()
以一种更紧凑的定义实现:它与常规map
相同,只是它与一元操作一起工作。它没有像常规的mapM
那样返回结果集m[b]
,而是将其丢弃。在这种情况下,它对您非常有用,因为您只对打印列表中的元素感兴趣
goOverList'' :: [String] -> IO ()
goOverList'' = mapM_ putStrLn
为了更加通用,我们可以使用print::Show a=>a->IO()
而不是putStrLn
,并在输入中接受每个“可显示”项目列表:
您的
goOverList
函数可以编写mapM_uuuuStrln
,其中mapM_uuu
是标准前奏曲中的一个函数
您还可以简化自己的实现:
goOverList :: [String] -> IO ()
goOverList [] = return ()
goOverList (x:xs) = do
putStrLn x
goOverList xs
sepp2k和solrize正确地推荐了
mapM
。但是,本着教你钓鱼而不是给你一条鱼的精神,以下是你将来可以尝试的东西:
(String->IO())->[String]->IO()
a
替换String
,以获取(a->IO())->[a]->IO()
,并搜索该字符串mapM\:Monad m=>(a->mb)->[a]->m()
,这正是您想要的。(第一个答案,closeFdWith::(Fd->IO())->Fd->IO()
不是相关的结果;第二个答案,traverse::(Foldable t,Applicative f)=>(a->fb)->ta->f()
是相关的,但理解和使用起来有点复杂。)
goOverList :: [String] -> IO ()
goOverList [] = return ()
goOverList (x:xs) = do
putStrLn x
goOverList xs