If you're interested in Haskell and are doing web dev, check out IHP, Haskell's version of Laravel/Rails/Django: https://ihp.digitallyinduced.com/ (Disclaimer: I'm founder of the company that makes IHP)
If you're interested in Haskell and are doing web dev, check out IHP, Haskell's version of Laravel/Rails/Django: https://ihp.digitallyinduced.com/ (Disclaimer: I'm founder of the company that makes IHP)
Looks like a good way of getting back into experimenting with haskell.
I'm pretty fluent in Haskell, but finding Haskell jobs is hard compared to OCaml or F#, which are a bit of a niche of their own. Actually, I routinely get OCaml offers when advertising Haskell on my CV. I find this interesting and exciting as OCaml was not very frequent outside academia a few years back.
Long statements, but I really do think employee retention and personal fulfillment would lead to a better working environment. So that is the way I’d argue it. Obviously a comprehensive sampling of performance metrics would be needed along with the more HR reasonings, but I think there are plenty of examples where Haskell is performing acceptably.
I just lost a big block of time because of this, please contextualize correctly that claim when you make it.
Support for dot-notation like it's documented at the proposals has been partially added. Field fetching is complete, field updates isn't released at all. It is being actively developed, and both bring very interesting features that you can't get in most languages - after all, it's Haskell - but it was only partially released up to now.
post <- fetch postId
>>= fetchRelated #comments
This is fine for simple form based CRUD apps.As you mentioned you're consuming the data with a JS frontend: For these cases we added a subsystem called DataSync to IHP. DataSync allows to use the IHP query builder directly from the JS side. This way we basically avoid needing to hand-write these nested graph API responses. Complex forms that depend on a lot of complex data can now be implemented using React components.
Here's an example query call from the JS:
const todos = await query('todos')
.where('id', 'd94173ec-1d91-421e-8fdc-20a3161b7802')
.or(where('id', '173ecd94-911d-1e42-dc8f-1b780320a316'))
.fetch()
This way the frontend can query data that it needs just in time. And also write records to the database without needing to manually writing API actions (thus avoid the data tree problem).You can find an example of this here: https://ihp.digitallyinduced.com/Guide/realtime-spas.html#bu... For web apps that are fully consumed by a single page app, we're right now building IHP Backend, which provides the IHP tooling + the DataSync API in a way that is way simpler than full stack IHP. If you're curious, you can find a demo video here: https://youtu.be/-jj19fpkd2c
Is this a language specific thing? Syntax? Underlying implementation of the language?
Is it a missing abstraction in the language?
I'm sure its possible to build something that compiles, but it would be so awful to use that you are better off with hand-written SQL where you need it, and N+1 stuff where you can get away with it.
I presume that the accessors in Haskell would be 1-1 with SQL language requests, but the problem is that SQL queries are not typed? Or are dynamically typed?
So, instead of a generic library for SQL queries, one would have to implement a library for a specific SQL DB structure?
So if you have a companies table joined to a contacts table, you'd get a two element tuple with a list of companies and a list of contacts, and then you have to iterate to do the joins and turn it into a JSON tree.
And there is no help at all for wanting to take in a tree of JSON data, and turn it into updates to existing records and inserts for new records.
You could have a library that to knows how to return a tree if you define a typeclass for the tree, but the only way I'd know to do it would be a separate tree data type for each result set. In Ecto you do have to define a structure that knows all the possible associations, but which associations you actually load in any given query is flexible, you can have associations that are not loaded eagerly for one query, and loaded eagerly in another. In Haskell I can't imagine doing that without two different tree structs, because there is nothing that would know how to take two differently typed result sets and make the same tree partially loaded.
Esqueleto has a function to avoid n+1's and return a map now:
https://hackage.haskell.org/package/esqueleto-3.5.3.0/docs/D...
https://www.foxhound.systems/blog/grouping-query-results-has...
https://hackage.haskell.org/package/rel8-1.3.0.0/docs/Rel8.h...
module Main where
import Rel8
import Data.Int
import Hasql.Statement
import Hasql.Session
import Hasql.Connection
import Database.Postgres.Temp
main = Database.Postgres.Temp.with $ \db -> do
Right conn <- acquire (toConnectionString db)
flip run conn $ statement () $ select $ do
q1 <- many $ do
r1 <- many (values [1 , 2 :: Expr Int16])
r2 <- many (values [3 , 4 :: Expr Int16])
values [(litExpr "one", r1), (litExpr "two", r2)]
q2 <- many $ do
r1 <- many (values [10 , 20 :: Expr Int16])
r2 <- many (values [30 , 40 :: Expr Int16])
values [(litExpr "ten", r1), (litExpr "twenty", r2)]
values [(litExpr "X", q1), (litExpr "Y", q2)]
> main
Right (Right [("X",[("one",[1,2]),("two",[3,4])]),("Y",[("ten",[10,20]),("twenty",[30,40])])])One if the things Haskell is best at is parsing and the resulting data structures are very nested.
What is an example data structure you think Haskell would struggle with? What language wouldn't struggle with that example?