I noticed that your blog post differed from the actual code in your git repository. In the blog post, you defined `shift` to be:
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.
Wow, excellent catch! I apologize for the discrepancy. I must have made a mistake simplifying the game code for the blog post. I created a Gist [1] to showcase the differences.
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:
Oh! So `go` is a function that's defined within `shift`. That's the crucial part I was missing. Why is it named "go"?
EDIT: While I have your attention, do you mind also pointing me to some resources to learn about this ">>=" operator? I recall it's something related to monads...