Arrays with rigid variable

后端 未结 2 999
轻奢々
轻奢々 2021-01-22 17:29

Well, I was doing a problem in which function I was using had a rigid variable. I had an idea of using arrays for that problem. So I thought of using arrays with same rigid vari

2条回答
  •  感情败类
    2021-01-22 18:33

    J. Abrahamson explained how to fix the errors at hand, but note that this is way overcomplicated. You can just omit all the local type signatures1, the compiler is able to infer those by itself. (There sure enough are applications where you need local type signatures, or where it's helpful for readability; then you often need ScopedTypeVariables. But not for such a simple function, IMO.)

    Speaking of unnecessary complexity — there is no benefit whatsoever in explicitly index-iterating through an array you've just created with listArray: it's pretty much equivalent (but much unwieldier) to just recursively destructing the list. And that can be written as a fold. Or, in cases like this where you iterate through two lists "in parallel", to folding on the zip of those lists. In fact you don't need even the fold: there's a good reason that (//) accepts a list of index-value pairs rather than just a single pair – because you'll normally want to update multiple elements2 in batch.

    That simplifies your function drastically:

    rearrange l la = elems $ posarr // zip l la
      where posarr = listArray (1, length l) la
    

    1So I'm not misunderstood: I really mean only local type signatures. On the top-level, everything should have a signature except perhaps completely trivial stuff that's only used inside your module (but then it's in a way also a local signature).

    2There is more to this than just convenience: your solution is actually very inefficient, because at each modification step a copy of the entire array needs to be made, so you can safely access the intermediate results in the purely functional language. Calling // with multiple pairs right away omits this: since the intermediate steps are never exposed, GHC can do magic under the hood, do destructive updates like you could in an imperative language (or in Haskell with the ST monad). Which is much faster.

提交回复
热议问题