I find this confusing. You still have all the cognitive burden to figure out what SQL you want to write, but then you have to translate that SQL into Haskell (or any other ORM).
I can see that this would be a benefit in the long run, but it wouldn't be familiar to most devs in the beginning. Similar to learning Haskell, once you get over the hurdle of the concepts then there's less to think about over all but there is still that initial gap.
Certainly the declaritive nature of SQL should be a very good fit for Haskell.
The types go a bit crazier than lists internally, but the aim is minimize the times manual intervention is required
Edit I don't mean this as an insult. I see it with a friend of mine who struggles with problem solving when not mapping to cat types
Yes, I remember a Dan Luu and another developer talking about something similar. The concepts like currying, composition and monads all work so smoothly in Haskell that you want to try to get them to work in other languages. It can make your code in those other languages worse because you're trying to get the language to do something it's not designed to do.
Further to that though then no one understands what you've written.
This is what Dan Luu said [0]:
> One was that I really got into functional programming and used a functional style everywhere I could. Immutability, higher-order X for any possible value of X, etc. The result was code that I could write and modify quickly that was incomprehensible to anyone but a couple of coworkers who were also into functional programming.
Beam is based on the relational algebra, which is the basis of SQL. Of course, it doesn’t enable a monkey to write database queries, but it does enable engineers who understand relational algebra to do so.
If your complaint is that you have to understand relational algebra to use a relational database, then your complaint is well out of the scope of beams domain.
Also, I have no idea what you mean about your friend. We can play the personal anecdote game all day long. When I was a JavaScript developer, I saw my fellow devs constantly testing for invariants that would be trivial with Haskell. We use JavaScript at work now too and they access our database indecently. Their queries do not enjoy the advantages beam provides and we’ll be switching to using a Haskell backend service soon instead
Also, I've found the cognitive burden to be significantly less using my beam library than writing SQL. The library handles everything. We freely join against queries (which may themselves be the results of joins, aggregates, window functions, etc). The SQL produced is what you'd expect. If you try to do something that is not straightforward on the backend, the library complains at compile time, and can even offer suggestions. We don't even need to worry about NULL, because the library makes heavy use of type families and such to guarantee you won't see a SQL NULL unless the type says so. If you use standard beam operators, we handle NULL sensibly. You can also drop to SQL NULL, if you want to have tighter control, but this causes the types to change, which means you can't do anything silly (like inadvertently throw out rows because your join condition now evaluates to NULL when you didn't want it to). Ultimately, using the type system is wonderful. Best of all, the types are mostly inferred. I rarely write out explicit type signatures. Despite the types carrying significant computation, all of that is given to us basically for free.
Once we have linear types in GHC, the migrations system will be able to check that a migration script is valid from beginning to end before the migration is even run! There's no way you could do that with any current tool I know of.
My guess for why big game engines aren't using higher-kinded types is that they are not available in any common systems level language. The only systems language I can think of with HKTs is ATS, which is a bit obtuse.
W.r.t cache efficiency, I've been working on a library to exploit the Haskell recursion-schemes package to transparently store and read data in a cache-intelligent way. It's certainly possible to do, it's just not necessary for most of the kinds of programs Haskellers write. At my last workplace we used Haskell for protocol parsing, and we were able to parse gigabits per second using just the standard Haskell containers and such. Haskell is quite a fast language, if you use it correctly. You rarely need heavy optimizations. Although obviously for game engines, you probably would.