【问题标题】:Understanding haskell's lazyness (foldl)了解haskell的惰性(foldl)
【发布时间】:2020-09-25 10:02:00
【问题描述】:

我有一个无限的键值对列表[(k, v)],我想创建一个从该列表派生的查找函数k -> v。当列表是有限的时,这可以使用 foldl 轻松完成,但是对于无限列表,这似乎更复杂。考虑下面的代码。使用createMapCustom 创建的查找会终止,而使用createMapFoldl 创建的查找不会。有什么办法可以让后者终止吗?

main :: IO ()
main = do
  let infList = map (\k -> (k, "value")) [0..]
  print $ createMapCustom infList 0
  print $ createMapFoldl infList 0

createMapCustom, createMapFoldl :: Eq k => [(k, v)] -> (k -> Maybe v)

createMapCustom [] _ = Nothing
createMapCustom ((k, v):xs) k'
  | k == k'   = Just v
  | otherwise = createMapCustom xs k'

createMapFoldl = foldl (\f ~(k, v) -> f `combine` (\k' -> if k' == k then Just v else Nothing)) (const Nothing)

combine :: (a -> Maybe b) -> (a -> Maybe b) -> (a -> Maybe b)
combine f1 f2 v = case f1 v of
  Just x  -> Just x
  Nothing -> case f2 v of
    Just x2 -> Just x2
    Nothing -> Nothing

【问题讨论】:

    标签: haskell


    【解决方案1】:

    这篇文章解释得很好https://www.reddit.com/r/haskell/comments/qrf54/why_does_foldr_work_on_infinite_lists_but_not/

    我应该使用 foldr 而不是使用 foldl,因为它是右辅助

    createMapFoldr = foldr (\(k, v) f -> (\k' -> if k' == k then Just v else Nothing) `combine` f) (const Nothing)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 2013-01-22
      • 1970-01-01
      • 2021-12-20
      • 2015-01-08
      相关资源
      最近更新 更多