【问题标题】:Implement the take function with list comprehension使用列表推导实现 take 函数
【发布时间】:2018-08-13 02:13:22
【问题描述】:

您将如何使用列表理解实现take

到目前为止我的方法:

take2 :: (Num i, Ord i) => i -> [a] -> [a]
take2 n xs = [x | x <- xs, [x..n]]

【问题讨论】:

  • 你为什么要为此使用列表推导?是的,严格来说这是可能的,但在这里这样做是相当不雅的。
  • 练习和好奇心:)

标签: haskell list-comprehension take


【解决方案1】:
take' :: Int -> [a] -> [a]
take' n xs = [xs !! i | i <- [0..n-1]]

【讨论】:

  • 仅代码的答案被认为是低质量的:请务必说明您的代码的作用以及它如何解决问题。如果您可以在帖子中添加更多信息,它将帮助提问者和未来的读者。另请参阅解释完全基于代码的答案:meta.stackexchange.com/questions/114762/…
【解决方案2】:

没有列表理解

take' :: Int -> [Int] -> [Int]
take' _ [] = []
take' _ [x] = [x]
take' n all@(x : xs)
        | (n > length all) = error "Index too large"
        | (n == length all) = all
        | (n == 0) = []
        | (n < length all) =  x : [] ++ (take' (n-1) xs)

【讨论】:

    【解决方案3】:

    列表推导不适合take 函数的根本原因是:

    take 函数在n 元素之后停止评估参数列表。

    但列表推导式总是评估生成器中列表的所有元素。 Haskell 中没有 break 语句。


    您可以在列表推导中使用之前或之后使用一些技巧来截断列表,但这样做并没有真正的意义。这类似于首先使用普通的take 截断列表,然后使用列表推导来返回结果。

    【讨论】:

      【解决方案4】:

      我们可以在这里使用zip 方法,并枚举元素和索引,例如:

      take2 :: (Num i, Enum i) => i -> [a] -> [a]
      take2 n xs = [x | (x, _) <- zip xs [1..n]]
      

      或使用ParallelListComp 扩展名:

      {-# LANGUAGE ParallelListComp #-}
      
      take2 :: (Num i, Enum i) => i -> [a] -> [a]
      take2 n xs = [x | x <- xs | _ <- [1..n]]
      

      但实际上take 可能不是一个适合列表理解的函数。

      【讨论】:

        猜你喜欢
        • 2019-08-26
        • 2011-07-24
        • 2013-03-30
        • 1970-01-01
        • 2013-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多