Hacker News new | ask | show | jobs
by imslavko 936 days ago
Oh yeah, a pure function that accepts previous state, and returns the new state is the pattern I use a lot.

The issue is that it is hard to do on complex graph structures in an algorithm where incremental changes happen to the graph O(n) times - it ends up creating complex code and complex execution that might be slow to pass the time limit on Codeforces, let's say.

In the OCaml world maybe this is the place where you say "screw it, this abstracted function does some stateful temporary business, but it looks pure from the outside" but in Haskell it's a lot harder to pull off without going deep into monads (and I forget how those work every time).

1 comments

Oh definitely go deep into monads. If you use the ST monad to do mutations, some people think Haskell provides nicer syntax to do imperative programming than traditional imperative languages like C. But of course such nicer syntax only comes from understanding and using important abstractions like monads, foldable, or traversable. Then there are niceties like automatic SoA/AoS transformation using type families.
I don't think I have heard of the automatic AoS/AoS before, do you have good links to study more?
You can read the documentation for the vector package. (This is an extremely common package since it is a dependency for the JSON library aeson.)

Check out https://hackage.haskell.org/package/vector-0.13.1.0/docs/Dat...

Now if you understand the type family GHC extension, all this will be easily understood. If not, basically the idea is that you can automatically transform Array of Structs into Structs of Array by defining that transformation using a data family instance that you write yourself. For common types like tuples, the library already defined polymorphic instances for you.

Of course this transformation isn't always desirable and you don't have to use this. If your code isn't performance sensitive I wouldn't even bother with unboxed vectors; I'd just use regular vectors.