11 comments

[ 3.7 ms ] story [ 34.0 ms ] thread
This is a really nice guide and I like the suggestions at the end. One extra suggestion that would at least be great for me with Haskell is specializing the names of the super generic functions. Like there’s no reason to keep the function names “traversable” and “sequenceA” for your specific Traversable. It’s the same as type synonyms being useful because, while it’s the same thing, intent is clearer.

I love the Haskell for its focus on reusable pieces, but I can’t keep up when I have to learn and remember all of those pieces to learn that ‘monoEndoSequentialAlternataverse mEmpty (.)’ is just a getter from your nifty key value store.

Here's what I do, for example:

  import qualified Data.List as DL
  import qualified Data.Map.Strict as DMS
and then in code, I use DL.foldl' or DMS.foldl' as needed. Not sure if that answers your question, though. (I also use classy-prelude, it's the best IMHO.)

You can also create your own functions as synonyms, if you feel like, it's easy and compiler has no issue with that. I often do that for structures (defined with "type") that I use in a module, to increase legibility.

Finally, the record dot syntax is becoming accepted to Haskell, it might help in writing IDEs that suggest methods based on types. (Peyton Jones explained somewhere that it's one of the advantages of method syntax, that it helps to show available methods.)

While I know it is subjective, it is still my person pet-peeve. Abbreviations like DL and DMS are really hard to read and remember. What I would have used instead is List and Map.
That's fine. I like to use these because they are visually distinct identifiers (and short), List and Map look like the type (class) names. I know it's a different namespace, but still..
hlint rules are nice for enforcing this, eg. you put sg. like this in your .hlint.yaml:

  - modules:
      - { name: [Data.List], as: List }
      - { name: [Data.Map, Data.Map.Strict], as: Map }
and then you get a hlint warning if you use DL/DMS instead of List/Map
> You can also create your own functions as synonyms, if you feel like, it's easy and compiler has no issue with that.

This is specifically what was trying to suggest. I wish folks would do more of it. Write the synonym for your function and then a brief docstring about what it means for this specific case.

All the generic tooling means that writing your getter or whatever might be simpler than it is in another language, but it's still worth writing. Even when it's just a synonym.

I think the article implies a bit of a strict convention for the apostrophe (which is used as an ascii prime mark), as implying a strict version of the unprimed name. I think it’s usage is more general and just means something “similar but slightly different” to the unprimed name.
I always liked x, xs and xss ("x", "x's", "excesses") but never sure if I'd have "got" them had I not been taught them in person...
this is the single most useful Haskell article I've seen

it is really nice to know there is some logic behind names like "liftA2" and "<<$>>"

before reading this they just seemed bafflingly arbitrary

I like articles like this that identify and address information gaps that aren't tackled by standard learning resources. Noticing these sorts of things that are just obvious to experts, because they picked them up over time, but are never explicitly explained to beginners, is a very useful skill.
Very good collection. To the standard type variables, I would add:

    i for an index
    s for state or stream
Also, in the context of lens specifically, s, t, u for the nth "containing structure" in the type signature.

There's a funny story Kmett told about exploring abstractions until he wound up with a type parameterized by i m a s t a b u and deciding he should probably call it quits when the code starts threatening him.