Wouldn’t the performance of HashMap Lookup be O(1)*, not O(log n)? It states the key value must implement hash and eq, ideally this means you eventually end up with a hash table, which would mean faster lookups.

What use of the C preprocessor are you seeing? Is it the #include? That does work like C’s #include but there are more module like things. See staload. These respect namespacing and local definitions so you can do things like:

#include in ATS code is textual substitution in ATS code and the code processed by the ATS compiler. Anything in C code blocks is directly inserted into the generated C code (ATS compiles to C which is then compiled by a C compiler) so is handled by the C compiler. ATS doesn’t parse that code. So there are two languages at play there, both using #include for similar functionality.

As a violinist, it’s important to me that I’m able to do as much as possible on my laptop without a trackpad. Small, precise movements - scrolling, selections - put a lot of tension in my bow hand’s index finger especially. I actually switched to vim recently in an attempt to wean myself off of trackpad dependency and I want to say I can feel an improvement…

I realize that a trackpad isn’t exactly a mouse but many people don’t carry mice around with them which makes it relevant here, I think.

This function allows looping over any monadic value. Works for values which represents state, configuration, IO, etc.

The example you copied uses print, I don’t know the imports but I’m guessing it’s the one from Prelude which has type (Show a) => a -> IO (). My manual type inference in my head says the example is using IO:

But this program is polymorphic. It can be instantiated as a monadic value, as long as it supports IO, Reader and State. A common use of this is to have one instantiation for production and one instantiation for tests. Yay, code reuse!!!

So the answer to your question:

How do I tell whether that is a maybe monad, a list monad, a continuation monad, or a state monad?

Forgive me if my understanding is incorrect here, but wouldn’t that only be true if you wrote all three of those functions yourself and a priori defined them in terms of such a triple-constrained monad? What if the three functions were provided by three authors and had types defined only in terms of a subset of the constraints?

I use something like the lens version (see the “Merging transformer layers” section) for other reasons but the point about StateT s1 (MaybeT (StateT s2 Identity)) definitely demonstrates a problem with MTL.

By type signatures. Or, if you’ve got monad-specific functions mixed in like State‘s get and put, then it becomes fairly obvious what sort of monad you’re dealing with. The code shown in the article could even be polymorphic w.r.t. the monad - assuming getData and co. are too.

I tend to use monads for “secondary” concerns - the kind of thing that I would consider leaving completely invisible if I were working in a language without monads. E.g. if working with state is the whole point of a given function then I’d probably have it accept and return the state in question rather than passing it via a state monad. So the <- just indicates “a secondary effect is going on here”, and if I wanted to know the specifics I’d mouse over one of the functions and see what the type signature is.

But yeah in code that mixes multiple monads there are cases where it would be nicer to have a way to distinguish. I wonder about an IDE using e.g. colour or underlines to show what monads were in play.