繁体   English   中英

在这种情况下如何避免显式递归?

[英]How can I avoid explicit recursion in this case?

我结束了这个骨架:

f :: (Monad m) => b -> m ()
f x = traverse_ (f . g x) =<< h x -- how avoid explicit recursion?
g :: b -> a -> b
-- h :: (Foldable t) => b -> m (t a) -- why "Could not deduce (Foldable t0) arising from a use of ‘traverse_’"
h :: b -> m [a]

如何避免f中的显式递归?

奖励:当我尝试将h[]概括为Foldable时, f不会进行类型检查( Could not deduce (Foldable t0) arising from a use of 'traverse_' )——我做错了什么?

更新:这是真正的代码。 Right用于递归名称为整数的安全摄像机镜头目录。 Left是处理名称不是整数的叶子的基本情况。

a <|||> b = left a . right b

doDir (Right d) = traverse_ (doDir . doInt) =<< listDirectory d 
  where doInt s = ((<|||>) <$> (,) <*> const) (d </> s) $ (TR.readEither :: String -> Either String Int) s

f = doDirg ~ doInt但被重构了一点。 h = listDirectory 为了回答奖金,我只是很傻,没有看到我必须结合所有定义来将类型绑定在一起:

f :: (Monad m, Foldable t) => (b -> a -> b) -> (b -> m (t a)) -> b -> m ()
f g h x = traverse_ (f g h . g x) =<< h x

如果您不介意在构建Tree时泄漏一点内存然后将其丢弃,则可以使用unfoldTreeM

f = unfoldTreeM (\b -> (\as -> ((), g b <$> as)) <$> h b)

我不相信有相应的unfoldTreeM_ ,但你可以写一个(使用显式递归)。 要概括超出Tree / []连接,您可能还喜欢refoldM 如果你在 Hackage 上搜索“hylomorphism”,你可以找到几个类似的函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM