It’s a short circuiting conjunction. Consider `aliceWantsADrink && bobWantsADrink`. If Alice doesn’t want a drink, she knows it’s not the case that both of them want a drink. Since she says “maybe” instead of “no” she signals to Bob that she wants a drink, and so he concludes they both want a drink.
I worked as a Haskell developer for a year and a half. The best productivity boost I had was switching to compiling on an EC2 instance. I saved battery, sped up compiles with greater parallelism than my XPS had cores for, and didn’t have to worry about cleaning up ~/.stack
Could you give a short explanation or link to a write up? Which size of EC2 instance works well for compiling Haskell? Does the EC2 live only for the duration of the compile, or permanently? If only for the duration, how do you deal with persisting the installed libraries to disk? Thanks!
I can’t recall exactly, I want to say 16 vCPUs and 64GB. How well a project can make use of the cores depends on how wide your dependency graph is vs how tall, as the unit of parallelism is a package.
The EC2 instance was on continuously, and I would ssh+tmux in. You could probably replace this with a server plugged in under your desk, depending on how much you trade off operational costs and capital costs.
More often than not I wanted passing tests to send something for review. If I needed an artifact, I would publish a docket image on an internal registry.
Also the “tf” in Printf in the example is syntax highlighted wrong.
Admittedly, I’d rather a development team spend more time and attention on their app than their landing page, but they should probably fix that since it kinda sticks out. Hopefully they’ll see these comments.
The example before shows the author typing Prin with autocompletion. Maybe that was the original intent? I think that context is lost though and it would be better to just highlight the entire thing as you suggest.
From the screenshot, it looks like the intention is that "Prin" has been typed by the user and "tf" is a suggestion, so it makes sense that "tf" would be gray and "Prin" would be green. (Of course, that could be made more clear.)
I swear it makes sense when you us it! But, the cursor is there. "Prin" before the insertion point, and the autocomplete suggestion of "t(<placeholder>)" comes after.
Makes sense! The image we're referring to is the one for the "Built for macOS" section, not the full screenshot at the top of the page. That one doesn't have a cursor in it.
I don’t think this an entirely fair comparison. STM provides essentially primitive operations, Async just builds a higher level API on top of them for common pattern. Not unlike the relationship between errgroup and go routines.
Strategies solve a different problem, in giving control of evaluation order of pure values. STM is aimed more at traditional multi threading
It also creates a filter for investment in the patch. If the submitter doesn’t bother to do a second round for trivial revisions, it would have been a waste of time for the maintainer to read the patch deeply.
I didn't read the hobgoblin the same way as the author being purely critical. I read it as a defense: a similarity between commands would make it easier to choose the wrong one. Removing a branch is a more destructive than deleting a file, so it should be a command chosen with conscious care rather than muscle memory.
I'd say it's good in the sense that it is readable provided you are familiar with the syntax for list comprehensions and appendings, and obviously correct if you know quicksort.
As an easy to follow (though questionably idiomatic) example, consider the typeclass Default:
class Default a where
def :: a
and an unwise pair of instances:
instance Default Int where
def = 7
instance Default String where
def = "foo"
This means I can say:
3 + def + length ("c" ++ def)
and get back 14. Note that which "def" depends on the type expected where it is used.
---
It's not limited to values, either. Consider the "return" function in the Monad typeclass:
return :: Monad m => a -> m a
which is a function that takes something and returns that something wrapped in a monad. Which monad? Whatever is expected at the call site.
[1, 2, 3] ++ return 4
gives us [1, 2, 3, 4] because list is a monad and return for lists gives a single element list, whereas
putStrLn "foo" >> return 4
gives us an IO action that, when executed, prints "foo" and yeilds a 4.
---
A super complex example is variadic functions like printf, with the type
printf :: PrintfType r => String -> r
PrintfType can be a String or IO (), giving you something like C's sprintf or printf based on the call site (which is itself cool), but it can also be a function that takes an instance of PrintfArg and gives back some new PrintfType (in an interesting intersection with currying).