elemIndex与splitAt Haskell联合使用

elemIndex与splitAt Haskell联合使用,haskell,maybe,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' wi

我是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'

现在我明白了为什么会发生这个错误,但是我不知道如何修复它。如果您有任何帮助,我们将不胜感激。

尽管该功能现在不安全,但应进行打字检查:

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,您希望从Maybe中提取Int并将其传递给splitAt函数。这就是fromJust函数所做的。fromJust将从Just数据类型中提取值


您可以尝试使用maybe或任何其他替代函数编写此函数的安全替代函数。

这应该进行类型检查,尽管该函数现在不安全:

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,您希望从Maybe中提取Int并将其传递给splitAt函数。这就是fromJust函数所做的。fromJust将从Just数据类型中提取值


您可以尝试使用maybe或任何其他替代函数编写此函数的安全替代函数。

您可以使用该函数,而不是使用索引,它在谓词第一次变为True的位置之前拆分列表

或者,由于您将丢弃第二部分,因此可以使用


不使用索引,您可以使用函数,该函数在谓词第一次变为True的位置之前拆分列表

或者,由于您将丢弃第二部分,因此可以使用

您可以这样做:

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! -}
然而,我同意哈马尔的看法。你并不是真的想把清单分成两部分;你只对其中一个部分感兴趣。因此,与其在列表中搜寻,不如找到所需的元素,返回其索引,然后再次在列表中搜寻,为什么不使用break或takeWhile?

您可以这样做:

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! -}

然而,我同意哈马尔的看法。你并不是真的想把清单分成两部分;你只对其中一个部分感兴趣。因此,与其在列表中搜索,不如找到所需的元素,返回其索引,然后第二次在列表中搜索,为什么不使用break或takeWhile?

谢谢Sibi我的代码现在可以工作了,但是您能解释一下$符号的用途吗?@RyanGibson$用于避免插入括号。fromJust$elemIndex x xs和fromJust elemIndex x x xs是一样的。谢谢Sibi,我的代码现在可以工作了,但是你能解释一下$符号的用途吗?@RyanGibson$用于避免插入括号。fromJust$elemIndex x x x x和fromJust elemIndex x x x x是相同的。