【问题标题】:Haskell concat / filter according specific rulesHaskell concat / filter 根据特定规则
【发布时间】:2019-11-14 13:01:26
【问题描述】:

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

  1. 没有递归的定义
  2. 没有理解列表
  3. 只允许使用 Prelude-Module。

现在我必须为 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 但我自己没有定义它 - 还是我错了?

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

【问题讨论】:

    标签: haskell higher-order-functions


    【解决方案1】:

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

    我们可以使用folding 代替递归和列表推导。以下解决方案使用函数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]
    

    【讨论】:

      【解决方案2】:

      你可以这样做;

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

      =&lt;&lt; 只是一元绑定运算符&gt;&gt;= 的翻转版本。

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

      【讨论】:

        猜你喜欢
        • 2019-10-17
        • 1970-01-01
        • 2018-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多