Function 组合多个Haskell函数
我想知道是否有一种简单的方法可以将这些函数组合在一起,使其更加干净。函数的目的是获取一个int列表,并返回一个列表,其中包含给定int出现之后出现的所有元素Function 组合多个Haskell函数,function,haskell,functional-programming,Function,Haskell,Functional Programming,我想知道是否有一种简单的方法可以将这些函数组合在一起,使其更加干净。函数的目的是获取一个int列表,并返回一个列表,其中包含给定int出现之后出现的所有元素 listAfterFinalKey:: [Int] -> Int -> [Int] 我的代码运行正常,我只是想知道是否有更好的编写方法。理想情况下,我希望所有功能都在一个函数中(listAfterFinalKey),但除了有三个单独的函数外,我不知道如何使它工作。我还避免任何内置库,以及诸如let和where之类的东西。如果有
listAfterFinalKey:: [Int] -> Int -> [Int]
我的代码运行正常,我只是想知道是否有更好的编写方法。理想情况下,我希望所有功能都在一个函数中(listAfterFinalKey
),但除了有三个单独的函数外,我不知道如何使它工作。我还避免任何内置库,以及诸如let和where之类的东西。如果有人能告诉我如何组合或压缩这些代码(如果可能的话),我将不胜感激
如果您真的想对函数式编程有一个良好的感觉,那么最好不要立即使用各种内置函数。然而,其中许多函数都是函数式编程的具体体现,因此学习如何使用它们,或者学习如何复制它们是很有用的 内置的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]
它不仅会在遇到目标之前删除所有元素,而且如果目标根本不存在,它还会返回原始列表。这也是OP函数的行为
一般来说,head
(和head'
)是不安全的,因为它在传递空列表时会引发异常。然而,在这个简单的函数中,这种情况永远不会发生,因为只有在我们知道xs
中至少出现一个target
的情况下才会调用tail'
还要注意的是,listAfterFinalKey
的类型比OP版本更通用。为什么要避免let
和where
?那么警卫呢?listAfterFinalKey xs x=tail$dropWhile(/=x)xs
。为什么要“避免内置库”?生成的列表应该没有x
了。尽管'listAfterFinalKey xs x=(reverse.takeWhile(/=x.reverse))仍然是一行代码xs@Li-瑶霞我的坏。你说得对。请@me下次让我知道:我正在避免让以及在哪里尝试更好地掌握函数式编程。我只是不知道是否有可能把它浓缩成一个或两个函数。
*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]