haskell - 在元素第一次出现时拆分列表

标签 haskell

我想知道是否有一个函数可以让我在第一次出现某个元素时拆分列表,排除该元素。基本上,假设:

listT= [1,3,2,5,6,3,2,6]

然后我想定义(或者不定义,如果它已经存在)一个函数 splitAtFirst 以便

splitAtFirst 2 listT = [[1,3],[5,6,3,2,6]]

到目前为止我的尝试如下:

splitAtfirst::(Eq a)=> a->[a]->[[a]]
splitAtfirst _ []=[]
splitAtfirst a (x:xs) 
   |a==x        = [xs]
   |otherwise   = [x]: splitAtfirst a (xs) 

但是,我明白了

>splitAtfirst 2 [1,3,2,5,6,3,2,6]
>[[1],[3],[5,6,3,2,6]]

我知道为什么会出现这个问题,但到目前为止我还没有找到好的解决方案

感谢任何帮助!

编辑:这是一个辅助函数,只有在检查 elem 是否在列表中后才会被调用,因此处理它不存在的情况并不是真正必要的。感谢您的帮助

最佳答案

由于 dfeuer 已经指出了修复您的实现的方法,我将只提供现成的解决方案:

splitAtFirst :: Eq a => a -> [a] -> ([a], [a])
splitAtFirst x = fmap (drop 1) . break (x ==)

splitAtFirst 实现了 dfeuer 答案中三个建议中的第二个选项。关于每个组件的一些注释:

  • (x ==) 是一个测试与 x 是否相等的函数,返回一个 Bool

  • break使用 bool 测试(此处为 (x ==))将列表分成两部分,第二个列表从通过测试的第一个元素开始。这两个列表作为一对返回(请参阅 dfeuer 的答案了解其原因)。

  • drop 1 如果列表中的第一个元素不为空,则将其删除(如果为空,则将其保留)。

  • fmap 需要相当长的时间才能正确解释,所以我只会说 fmap f 应用于一对(例如 break) 将函数 f 应用于该对的第二个元素。在我们的例子中,fmap (drop 1) 将删除第二个列表的第一个元素——即分隔符。 (要了解有关 fmap 的更多信息,请搜索关键字“functor”,或者尝试在列表或 Maybe 值上使用它,看看会发生什么。)

关于haskell - 在元素第一次出现时拆分列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40297001/

相关文章:

haskell - 如何理解 Haskell 函数参数

haskell - 我如何在 Haskell 中显示派生树?

haskell - 'Either e` 包中 `Failure` 的 "failure"实例存在问题

haskell - 使用 Haskell 的 "Maybe",类型声明[初学者的问题]

opengl - Haskell opengl 纹理 GLFW

haskell - 在 Haskell 中切换实例声明的参数顺序

haskell - 为什么 Data.HashTable 使用盐散列(来自 Data.Hashable)?

haskell - 为什么 GHC 会在这里产生等式约束错误而不是类型匹配错误?

haskell - 如何实现与 invokeAll 等效的 Haskell

haskell - 查找树的深度 haskell