我对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'
现在我明白为什么会出现这个错误,但是我不明白我是如何解决的。任何帮助将不胜感激。
答案 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! -}
然而,我同意哈马尔。您并没有真正尝试将列表分成两部分;您只对这些部分的一个感兴趣。因此,而不是搜索列表,找到你想要的元素,返回它的索引,然后第二次搜索列表,为什么不只是使用break
或takeWhile
?