5 ms·
With the state monad (State not StateT) you can run it in pure code because the runner is pure. It only “mutates” one context and when it’s all unwrapped it’s a
by efnx 9y ago
With the state monad (State not StateT) you can run it in pure code because the runner is pure. It only “mutates” one context and when it’s all unwrapped it’s actually pure functions all the way down.
- tome 9y agoYou probably meant ST, but yes, much to nnq's surprise, this is possible!
- gowld 9y agoThe fact that something called "ST" is one of the most important libraries in the language, and it's the one that you should choose for State (leave aside the "State" library! that's not the one you want!) shows how for all Haskell's power, it's terribly unusable for trivial reasons that never get fixed due to extreme deference to legacy mistakes. See also: Prelude.
- tome 9y agoIt's not one of the most importart libraries in the language. It's hardly used.
- tathougies 9y agoST is not the monad that should be used for state. You should use State for that. ST is an optimization trick mainly used by framework implementors. In my professional experience writing Haskell, I’ve never seen st used for anything important
- dllthomas 9y ago"mainly used by framework implementors" IMO it's data structures and algorithms - specifically those where mutation gives substantial speed improvement (which isn't all by any stretch) - more than "frameworks" as typically conceived...
- gowld 9y agoI wouldn't call "mutable arrays" an optimization trick mainly used by framework implementors, or "not important" https://wiki.haskell.org/Arrays https://wiki.haskell.org/Arrays
- efnx 9y agoI’ve never had to use ST. I most definitely meant State, which is what I wrote in the grandfather post.
- kqr 9y agoExplanation for innocent bystanders: The State type is just a convenient wrapper around regular functions. State makes it look, syntactically, like mutation is happening. You can use it to implement real mutable algorithms etc. But onces unfolded, it's just function calls. ST, on the other hand, wraps true mutation. Is extends its secret magic sauce hooks into the compiler and will generate real, actual (thread-local) mutation under the hood, in a way that guarantees the effects cannot escape the current context in which mutation is allowed.
- nnq 9y agonot sure if this should stimulate me to re-try Haskell, or to totally scare me :)
- dllthomas 9y agoThe former :D As elaborated below that comment, State isn't actually mutating anything, it's just hiding away the boiler plate of threading an extra parameter through your functions. ST, on the other hand, is compiler magic akin to transients in Clojure - STRefs actually get mutated, below a pure context. But type magic ensures that STRefs can't persist across multiple "runs" of the ST value, so it still behaves like pure code. So it's actually a little less scary than Clojure's transients, although you're more likely to encounter the word "skolem".