Tail optimization guarantee - loop encoding in Haskell

后端 未结 2 1146
走了就别回头了
走了就别回头了 2020-12-16 17:38

So the short version of my question is, how are we supposed to encode loops in Haskell, in general? There is no tail optimization guarantee in Haskell, bang pattern

2条回答
  •  春和景丽
    2020-12-16 18:12

    OK let's work from the ground up here.

    You have a list of entries

    entries = [(k,j) | j <- [0..jmax], k <- [0..kmax]]
    

    And based on those indexes, you have tests and counts

    tests m n = map (\(k,j) -> j + k == m + n - 3) entries
    counts = map (\(_,j) -> if (rem j 3) == 0 then 2 else 1) entries
    

    Now you want to build up two things: a "total" count, and the list of entries that "pass" the test. The problem, of course, is that you want to generate the latter lazily, while the former (to avoid exploding the stack) should be evaluated strictly.

    If you evaluate these two things separately, then you must either 1) prevent sharing entries (generate it twice, once for each calculation), or 2) keep the entire entries list in memory. If you evaluate them together, then you must either 1) evaluate strictly, or 2) have a lot of stack space for the huge thunk created for the count. Option #2 for both cases is rather bad. Your imperative solution deals with this problem simply by evaluating simultaneously and strictly. For a solution in Haskell, you could take Option #1 for either the separate or the simultaneous evaluation. Or you could show us your "real" code and maybe we could help you find a way to rearrange your data dependencies; it may turn out you don't need the total count, or something like that.

提交回复
热议问题