infinite lists, lazy evaluation and length

后端 未结 3 1134
南方客
南方客 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:09

    is length actually iterating the whole list to give a response?

    Yes.

    I guess length is to be avoided every time I try to implement something working well with the lazy evaluation

    Not just that, it also gives you bad runtimes when laziness isn't a factor (being O(n) in cases where an O(1) check often suffices1), so you should avoid it most of the time in general.

    how can I improve my example to work with infinite lists?

    You don't need to check whether the length of the list is less than n, you just need to check whether it's zero. And that you can do with a simple pattern match.


    1 For example something like f xs | length xs >= 2 = ..., which is O(n), can be replaced with f (x1 : x2 : xs) = ..., which is O(1).

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2021-01-24 22:19

    is length actually iterating the whole list to give a response?

    Yes, absolutely.

    length is to be avoided every time I try to implement something working well with the lazy evaluation

    Yes, absolutely.

    so there is some alternative?

    Yes: solve the problem without referencing length. There are no general methods of problem solving so you need to work out each specific case.

    how can I improve my example to work with infinite lists

    You are a railroad worker. A huge train if cars begins where you are standing and stretches over the horizon. You have no idea where it ends, if ever. Your job is to separate it into small trains of three cars each. How do you proceed?

    0 讨论(0)
提交回复
热议问题