我想知道是否有一种简单的方法可以将这些功能组合在一起,使其更加干净。该函数的目的是获取一个int列表,并返回一个列表,其中包含在给定的int出现后发生的所有元素。
listAfterFinalKey:: [Int] -> Int -> [Int]
我的代码有效,我只是想知道是否有更好的编写方法。理想情况下,我希望将它全部放在一个函数中(listAfterFinalKey
),但我不知道如何让它工作,而不是有三个独立的函数。我也避免在库中进行任何构建,以及诸如let和where之类的东西。如果有人能告诉我如何组合或压缩一些代码(如果可能的话),我将不胜感激。
listAfterFinalKey:: [Int] -> Int -> [Int]
listAfterFinalKey [] x = []
listAfterFinalKey x y = helperFunction1 x y (checker x y 0)
checker:: [Int] -> Int -> Int -> Int
checker [] tracker count = count
checker (x:xs) tracker count = if tracker == x
then checker xs tracker (count+1)
else checker xs tracker count
helperFunction1:: [Int] -> Int -> Int -> [Int]
helperFunction1 [] tracker count = []
helperFunction1 x tracker count = if (count == 0)
then take 1 x ++ helperFunction1 (drop 1 x) tracker count
else if (count /= 0) && (tracker == (head x))
then helperFunction1 (drop 1 x) tracker (count-1)
else helperFunction1 (drop 1 x) tracker count
答案 0 :(得分:1)
如果你真的想要对函数式编程有一个良好的感觉,可以不立即使用各种内置函数。然而,其中许多函数都是函数式编程的体现,所以学习使用它们很有用,也许还可以学习如何复制它们。
内置的Haskell模块(事实上,我遇到的所有Haskell模块)都是开源的,因此您可以轻松查看它们的实现方式。
为了重现上述行为,您可以实施自己的elem
,dropWhile
和tail
版本:
elem' :: Eq a => a -> [a] -> Bool
elem' _ [] = False
elem' target (x:xs) | target == x = True
elem' target (_:xs) = elem' target xs
dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' _ [] = []
dropWhile' p (x:xs) | p x = dropWhile' p xs
dropWhile' _ xs = xs
tail' :: [a] -> [a]
tail' (_:xs) = xs
这三个功能非常类似于他们的“官方”功能 - 我刚刚为这三个功能添加了'
作为后缀。
现在,您可以使用这三个构建块轻松实现listAfterFinalKey
:
listAfterFinalKey :: Eq a => [a] -> a -> [a]
listAfterFinalKey xs target | not (elem' target xs) = xs
listAfterFinalKey xs target = tail' (dropWhile' (/= target) xs)
据我所知,它的行为与OP版本相似:
*Q48735389> listAfterFinalKey [0..9] 3
[4,5,6,7,8,9]
*Q48735389> listAfterFinalKey [0..9] 11
[0,1,2,3,4,5,6,7,8,9]
*Q48735389> listAfterFinalKey [0..9] (-1)
[0,1,2,3,4,5,6,7,8,9]
*Q48735389> listAfterFinalKey [1,2,3,2,1] 2
[3,2,1]
它不仅会在遇到target
之前删除所有元素,而且如果target
根本不存在,它也会返回原始列表。这是AFAICT,也是OP功能的行为。
通常,head
(和head'
)是不安全的,因为它在传递空列表时会抛出异常。但是,在这个简单的函数中,永远不会发生这种情况,因为tail'
仅在我们知道的情况下被调用,target
中至少出现xs
}。
另请注意,listAfterFinalKey
的类型比OP版本更为通用。