If you ignore the power of Haskell's type system, and write all your code imperatively in the IO Monad, and continue to write large functions that do many things instead of writing smaller functions that can be composed, you gain almost nothing from Haskell, and you might have been better off writing your code in another language.
the type system allows abstraction to a much higher degree than in languages with weaker type systems
That may be true, but that's simply irrelevant in this case. The type system is not being used in [1] for any interesting searches (proofs, return type polymorphism, overload resolution, etc) here outside of the most trivial of polymorphic literals. Every standard library function in use here works practically identically in any functional language, including dynamic ones such as Clojure.[1]: http://taylor.fausak.me/2014/04/28/cloning-2048-in-haskell/
shift v = pad
(map Just (concatMap add (group (catMaybes v)))))
Nothing
(length v)
whereas the code gives: shift v = take n (v' <> empty n)
where
n = length v
v' = group (filter isJust v) >>= go
go (Just a : Just b : ts) = Just (a + b) : go ts
go ts = ts
From my understanding of the blog post's logic, the former doesn't handle the case where `v = replicate 4 (Just 2)`, since it returns `[Just 4, Just 2, Just 2, Nothing]`. Am I correct, and if so, why does the latter version fix this problem? For reference, I know little to no Haskell.The problem in the blog post is the `add` function. It should recurse (like `go` in the Hs2048 package). I fixed the post [2] with this line:
add (x : y : rest) = x + y : add rest
[1]: https://gist.github.com/tfausak/4401ef0b43b5c1db0570
[2]: https://github.com/tfausak/tfausak.github.io/issues/31Further, the animation code is only a miniscule fraction of that code base.
I'll have to dig through the code again. The polish that the end product of the first version exhibited is well beyond that of any of the rewrites I've seen. To the point that it is, in fact, jarring. And makes it frustrating to read how much nicer the code looks in some of them.
Really brings home the point that intrinsic quality is nice, but pails in comparison to the final quality of the overall product. It isn't that I am convinced the sausage making process is always gross. Just that I have not seen that many examples where the clean versions are anything more than just sterilizations that have killed a lot of the original.