elemIndex与splitAt Haskell一起使用

时间:2014-04-15 12:16:57

标签: haskell maybe

我对Haskell很陌生,无法弄清楚如何解决以下问题。

我必须实现以下功能" ca"它接受一个列表和一个元素,并删除输入元素后列表中的所有其他元素:

ca:: Eq a => a -> [a] -> [a]

我不允许更改任何功能类型,并且到目前为止已经提出以下代码:

ca x xs = let (ys, zs) = splitAt (elemIndex x xs) xs in ys 

这会产生以下错误:

couldn't match expected type 'Int' with the actual type 'Maybe Int'

现在我明白为什么会出现这个错误,但是我不明白我是如何解决的。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

这应该是类型检查,尽管现在功能不安全:

import Data.List
import Data.Maybe (fromJust)

ca x xs = let (ys, zs) = splitAt (fromJust $ elemIndex x xs) xs in ys

原因是elemIndex类型为elemIndex :: Eq a => a -> [a] -> Maybe Int,您希望从Int中提取Maybe并将其传递给splitAt函数。这是fromJust函数的作用。 fromJust将从Just数据类型中提取出值。

您可以尝试使用maybe或任何其他替代功能编写此功能的安全替代方案。

答案 1 :(得分:0)

你可以这样做:

let 
  Just n = elemIndex x xs
  (ys, zs) = splitAt n xs
in ys

但是,如果指定的元素不存在,由于"模式匹配失败",这将引发异常。更好的方法是:

case elemIndex x xs of
  Just n  -> let (ys, zs) = splitAt n xs in ys
  Nothing -> {- decide what to do if there's no match! -}

然而,我同意哈马尔。您并没有真正尝试将列表分成两部分;您只对这些部分的一个感兴趣。因此,而不是搜索列表,找到你想要的元素,返回它的索引,然后第二次搜索列表,为什么不只是使用breaktakeWhile