小编Pro*_*het的帖子

将元组作为参数解构时,无限列表上的 Haskell 元组解构与使用 let 解构时的行为不同

当尝试使用 foldr 实现 dropWhile 时,我想出的第一个算法是

dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' pred = fst . foldr (\cur (acc, xs) ->
    if pred cur
    then (acc, cur:xs)
    else (cur:xs, cur:xs)) ([], [])

Run Code Online (Sandbox Code Playgroud)

虽然这有效,但它会导致无限列表上的堆栈溢出而没有给出任何值。因为我不确定,为什么这不起作用,我只是玩弄这个函数,直到我想出这个:

dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' pred = fst . foldr (\cur t -> let (acc, xs) = t in
    if pred cur
    then (acc, cur:xs)
    else (cur:xs, cur:xs)) ([], [])
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这个和第一个之间的唯一区别是,这里我在(acc, xs)let 绑定中解构元组,而不是直接在函数参数内部解构。出于某种奇怪的原因,此代码适用于无限列表。如果有人知道为什么会这样,请告诉我。

haskell tuples list destructuring lazy-evaluation

5
推荐指数
1
解决办法
104
查看次数

Haskell Data.Map 同时查找和删除

我最近使用了 State Monad 内部的Map类型Data.Map,所以我想写一个函数,它在 Map 中查找一个值,并从 State Monad 内部的 Map 中删除它。我当前的实现如下所示:

lookupDelete :: (Ord k) => k -> State (Map k v) (Maybe v)
lookupDelete k = do
    m <- get
    put (M.delete k m)
    return $ M.lookup k m
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但感觉效率很低。使用命令式语言中的可变映射,找到delete函数并返回被删除的值的情况并不少见。我找不到这个功能,所以如果有人知道一个(或可以解释为什么没有),我将不胜感激

lookup dictionary haskell

3
推荐指数
2
解决办法
214
查看次数

为什么 Data.Map.Map 不是 Bifunctor?

在 a 中存储数据时Map,我最近在寻找一个Bitraversable实例,因为我想遍历键和值。令我惊讶的是,我发现Map它甚至没有Bifunctor实例,即使first( mapKeys) 和second( map) 的实现都存在。

是否有特定原因,或者这个决定只是为了最大限度地减少依赖性?

谢谢

containers dictionary haskell bifunctor

1
推荐指数
1
解决办法
65
查看次数