And*_*llo 0 recursion lambda haskell
我有以下代码,它采用一个列表,检查每个元素的值是否高于avg和,就是这样,打印val - avg.我已经用递归实现了它,我想转换它以便使用map函数.
loop [] = return ()
loop (x:xs)
| x > average = print (x - average) >> loop xs
| otherwise = loop xs
Run Code Online (Sandbox Code Playgroud)
有什么建议吗?
请注意,每个步骤同时loop执行两项操作:它们(可能)从列表的每个元素生成打印操作,然后将该操作与其余操作组合(使用(>>)).如果你想写loop来讲map,你需要理清这两个子步骤.例如,您可以定义一个函数......
printDiffIfAboveAvg :: Double -> IO ()
Run Code Online (Sandbox Code Playgroud)
...然后将其应用于列表的所有元素map printDiffIfAboveAvg.这将为您提供类型的操作列表[IO ()],您需要将这些操作合并为一个整体操作:
runAllActions :: [IO ()] -> IO ()
Run Code Online (Sandbox Code Playgroud)
runAllActions已经存在于基础库中,在更通用的版本中称为sequence_:
sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
Run Code Online (Sandbox Code Playgroud)
所以你会的loop = sequence_ . map printDiffIfAboveAvg.实际上,基础库中还有另一个功能......
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
Run Code Online (Sandbox Code Playgroud)
...执行的正是这种组合sequence_和map.