我试图通过附加一个数字来找到目录名,直到找到一个尚不存在的名称:
head <$> filterM (fmap not . fexists_) [ getDatedDir t d n | n <- [0..] ]
Run Code Online (Sandbox Code Playgroud)
这个问题是它永远不会回来.我认为问题是尽管IO是一个Functor,但filterM必须在头部效果之前完成所有IO; 也就是说,它必须为每个n评估fexists - 这当然是无限的.
现在,我可以解决这个问题:
go t d 0
where go t d n = do
let dir = getDatedDir t d n
fexists_ dir >>= \case
False -> return dir
True -> go t d (n+1)
Run Code Online (Sandbox Code Playgroud)
但我觉得应该有更优雅的方法,使用filterM或类似的东西.
这感觉就像一个普通的模式,在Control.Monad中可能存在一个提升功能,我只是没有看到它.
有firstM来自Control.Monad.Loops:
firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
Run Code Online (Sandbox Code Playgroud)
返回满足给定谓词的列表中的第一个值(如果有).
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |