infinite lists, lazy evaluation and length

后端 未结 3 1187
南方客
南方客 2021-01-24 21:27

Haskell noob here: I\'m still trying to understand the mechanics of the language, so if my question is plain stupid, forgive me and point me to some link which I can learn from

3条回答
  •  半阙折子戏
    2021-01-24 22:11

    Another trick you can do (which I've seen in Data.Text, but am surprised is not in Prelude for lists in general) is to make length short-circuit as soon as possible by returning an Ordering rather than a Bool.

    compareLength :: [a] -> Int -> Ordering
    compareLength [] n = compare 0 n
    compareLength _ 0 = GT
    compareLength (x : xs) n = compareLength xs (n - 1)
    

    Then you can use it in chunks.

    chunks :: Int -> [a] -> [[a]]
    chunks n xs = case compareLength xs n of
                       LT -> [xs]
                       _  -> let (ch, rest) = splitAt n xs in ch:chunks n rest
    

    And this works fine.

    *Main> take 4 $ chunks 3 [1..]
    [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
    

    For this particular case, other implementations might be more idiomatic, but hopefully this is a nice trick to know.

提交回复
热议问题