如何使用列表推导实现take
?
到目前为止我的方法:
take2 :: (Num i, Ord i) => i -> [a] -> [a]
take2 n xs = [x | x <- xs, [x..n]]
答案 0 :(得分:8)
列表推导不适合take
函数的根本原因是:
take
函数会在n
元素之后停止参数列表的评估。
但列表理解始终评估生成器中列表的所有元素。 Haskell没有中断声明。
你可以使用一些技巧在列表推导中使用它之前或之后截断列表,但是没有真正的意义。这类似于首先使用普通take
来截断列表,然后使用列表推导来返回结果。
答案 1 :(得分:7)
我们可以在这里使用SELECT s.id, s.jid, s.jd, s.tos, s.toffs, s.miles, s.mrate, s.r1, s.r2, s.r3, s.r4, s.r5, s.r6, s.r7, s.r8,
j.cid, j.cc, j.ref, j.ac, j.reference, j.status, j.jdesc
FROM jobs j LEFT JOIN
jSheets s
ON s.jid = j.id AND s.jd >= :jd AND s.jd <= :jd2
WHERE j.cc = :cc
ORDER BY s.id DESC
方法,并枚举元素和索引,例如:
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]]
可能不是一个最适合列表理解的函数。
答案 2 :(得分:0)
没有列表理解
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 :(得分:0)
take' :: Int -> [a] -> [a]
take' n xs = [xs !! i | i <- [0..n-1]]