首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >查找列表中元素的前面元素(Haskell)

查找列表中元素的前面元素(Haskell)
EN

Stack Overflow用户
提问于 2016-08-16 01:21:24
回答 4查看 1K关注 0票数 2

我想返回列表中元素的前一个元素。我打算得到参数的索引,并使用它来表示反对列表,这样参数是最后一个元素,然后反转它,然后取反列表的第二个元素。我得到了错误:输入elemIndexMaybe Int,而take函数需要Int。我想要修复它或者用简单的递归编写代码,是否有更短的使用递归的代码?

代码语言:javascript
运行
复制
precedingElement :: Eq a => a -> [a] -> Maybe a
precedingElement elt lst    | lst == [] = error "List is empty"
                            | elt `notElem` lst = Nothing
                            | otherwise = Just x where x = snd (reverse (take (elt `elemIndex` lst) lst))
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-08-16 01:27:20

为了返回给定元素的前一个元素,可以使用一些模式匹配和递归:

代码语言:javascript
运行
复制
precedingElement _ [] = Nothing
precedingElement _ [x] = Nothing
precedingElement elt (x:y:rest)
    | y == elt = Just x
    | otherwise = precedingElement elt (y:rest)
票数 5
EN

Stack Overflow用户

发布于 2016-08-16 08:38:09

对于这样的问题,我最喜欢的一个被低估的实用程序相当方便。让我有倒向列表,这样我就不需要反转我的大脑了。

代码语言:javascript
运行
复制
data Bwd x = B0 | Bwd x :< x  -- rightmost is nearest

把列表元素想象成算盘线上的珠子。向左轻击几下,让你的手指放在下一个上。你有什么?手指左边的珠子列表(最右边的),手指右边的珠子列表(最左边的珠子),还有你手指上的珠子。

也就是说,列表的单孔元素上下文是由孔的任何一边的前向和后向列表给出的。

代码语言:javascript
运行
复制
type ListContext x = (Bwd x, [x])

那些知道我的老歌的人认为ListContext[]的衍生词。

焦点的一个元素(你的手指在珠上)是

代码语言:javascript
运行
复制
type ListFocus x = (ListContext x, x)

还有一个有用的操作,用它的上下文装饰每个list元素,并将其放在焦点上。

代码语言:javascript
运行
复制
focus :: [x] -> [ListFocus x]
focus = go B0 where
  go xz [] = []
  go xz (x : xs) = ((xz, xs), x) : go (xz :< x) xs

例如,

代码语言:javascript
运行
复制
focus [1,2,3] = [((B0,[2,3]),1), ((B0 :< 1,[3]),2), ((B0 :< 1 :< 2,[]),3)]

现在很容易回答与元素及其周围环境有关的各种问题。您可能不应该仅仅为了解决这个问题而构造focus,但这是我一直关注的事情,因为它解决了许多问题。

代码语言:javascript
运行
复制
[p | ((_ :< p,_),q) <- focus xs, q == x]

计算位于px左侧的所有值xs。如你所见。

(顺便说一句,这个focus操作不是从哪里来的。它源于列表的数据类型的差异结构。This answer (在这里被称为picks)更详细地讲述列表故事,this answer开发了数据类型通用故事。

票数 9
EN

Stack Overflow用户

发布于 2016-08-16 03:44:01

因为我是一个狂热的粉丝,我可能会写一些东西

代码语言:javascript
运行
复制
lastBefore :: (a -> Bool) -> [a] -> Maybe a
lastBefore p xs = foldr go (`seq` Nothing) xs Nothing
  where
    go x r (Just prev) | p x = Just prev
    go x r _ = r (Just x)

但我必须检查GHC是否可以按我的意愿优化它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38965291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档