Haskell根据特定规则进行连接/筛选



根据以下规则,我试图解决以下问题:

  1. 没有递归的定义
  2. 没有理解列表
  3. 只允许使用前奏模块

现在我必须为concatfilter实现高阶。

此时此刻:

concat' :: [[a]] -> [a]
concat' a = (concat a)
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs) 
| p x = x : filter p xs
| otherwise = filter p xs

concat函数正在工作(到目前为止没有什么特别的(->这是一个定义的递归吗?我的意思是,我使用了标准前奏中预定义的concat,但我自己没有定义它——或者我错了吗?

对于过滤器,我已经查找了标准前奏的定义,但它要么不起作用,要么包含递归的定义。

我认为应该避免使用concatfilter函数。如果concatfilter已经可用,我们为什么需要实现它们?所以试着从头开始实现它们。

我们可以使用折叠来代替递归和列表理解。以下解决方案使用函数foldr

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
concat' :: [[a]] -> [a]
concat' = foldr (++) []
filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (x acc -> if p x then x:acc else acc) [] 

示例:

main = do
print $ concat' ["A", "B", "CAB"]    -- "ABCAB"
print $ filter' (x -> x `mod` 2 == 0) [1..9]  -- [2, 4, 6, 8]

您可以执行以下操作;

concat' :: Monad m => m (m b) -> m b
concat' = (id =<<)
filter' p = ((x-> if p x then [x] else []) =<<)

CCD_ 6只是一元绑定运算符CCD_ 7的翻转版本。

filter' (< 10) [1,2,3,10,11,12]
[1,2,3]

最新更新