A one- or two-page diagram of how Haskell works?

When I write C, or even C++, I have a mental model of how execution will proceed. When I write Prolog, but get confused, I run a kind of skeletal inference algorithm in my head and the confusion usually clears up. I can imagine how things are stored and what's done with them. I can see /through/ the code to the machine. With Haskell, I still feel blind. Has anyone summarized it all in a chart where I can look at it and think, "Ah, OK, GHC is taking this line and thinking of it THIS way"? If someone wanted to write an interpreter for Haskell, would there be a way for them to see how it would basically need to work, in one chart? Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner@projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry

Wonderful question. I would love to see something like this too. What kind of confusion are you running into with Haskell? Are they of the type error variety, or do you have a well-typed program that doesn't do what you want? *If* it is the type error stuff, I would recommend that you give the compiler information about what you think the types are. The reason is that type information can flow from very far away places than where you are getting an error. For example, I was writing this code the other day: *for eIdpData \ $(schoolId, districtId, tenantId) -> pure $ Right 1* The type of for is *for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)* In my case, I knew the following: *t ~ Either SyncFailure* *a ~ IdpData* *f ~ WriterT Logs m* *b ~ Int* Once I do replace type variables with concrete types / type constructors, it becomes clear that my function argument should return an *Int* in some structure, and instead I am returning an *Either a Int*. This helps me figure out the problem. Writing out takes a lot longer than actually doing it. Anyway, the key is to provide GHC with the information you think you know; this will prevent type inference from allowing type information to flow from far away places, and the error will become clearer or at the very least more localized. On Wed, Jun 23, 2021 at 11:42 PM Michael Turner < michael.eugene.turner@gmail.com> wrote:
When I write C, or even C++, I have a mental model of how execution will proceed.
When I write Prolog, but get confused, I run a kind of skeletal inference algorithm in my head and the confusion usually clears up. I can imagine how things are stored and what's done with them. I can see /through/ the code to the machine.
With Haskell, I still feel blind.
Has anyone summarized it all in a chart where I can look at it and think, "Ah, OK, GHC is taking this line and thinking of it THIS way"? If someone wanted to write an interpreter for Haskell, would there be a way for them to see how it would basically need to work, in one chart?
Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner@projectpersephone.org
Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone
"Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Steven Leiva 305.528.6038 leiva.steven@gmail.com http://www.linkedin.com/in/stevenleiva

A few caveats to the above:
1) The literal *1* is polymorphic, but I hand-waved over that for now
2) *Either e Int* is an *Int* in *some* structure, but it's not the
structure we want. In the type signature for *for*, the function argument
does not contain the *t* type variable at all, which, again, is in our case *t
~ Either SyncFailure*.
On Thu, Jun 24, 2021 at 9:43 AM Steven Leiva
Wonderful question. I would love to see something like this too.
What kind of confusion are you running into with Haskell? Are they of the type error variety, or do you have a well-typed program that doesn't do what you want?
*If* it is the type error stuff, I would recommend that you give the compiler information about what you think the types are. The reason is that type information can flow from very far away places than where you are getting an error. For example, I was writing this code the other day:
*for eIdpData \ $(schoolId, districtId, tenantId) -> pure $ Right 1*
The type of for is *for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)*
In my case, I knew the following:
*t ~ Either SyncFailure* *a ~ IdpData* *f ~ WriterT Logs m* *b ~ Int*
Once I do replace type variables with concrete types / type constructors, it becomes clear that my function argument should return an *Int* in some structure, and instead I am returning an *Either a Int*. This helps me figure out the problem.
Writing out takes a lot longer than actually doing it. Anyway, the key is to provide GHC with the information you think you know; this will prevent type inference from allowing type information to flow from far away places, and the error will become clearer or at the very least more localized.
On Wed, Jun 23, 2021 at 11:42 PM Michael Turner < michael.eugene.turner@gmail.com> wrote:
When I write C, or even C++, I have a mental model of how execution will proceed.
When I write Prolog, but get confused, I run a kind of skeletal inference algorithm in my head and the confusion usually clears up. I can imagine how things are stored and what's done with them. I can see /through/ the code to the machine.
With Haskell, I still feel blind.
Has anyone summarized it all in a chart where I can look at it and think, "Ah, OK, GHC is taking this line and thinking of it THIS way"? If someone wanted to write an interpreter for Haskell, would there be a way for them to see how it would basically need to work, in one chart?
Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner@projectpersephone.org
Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone
"Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Steven Leiva 305.528.6038 leiva.steven@gmail.com http://www.linkedin.com/in/stevenleiva
-- Steven Leiva 305.528.6038 leiva.steven@gmail.com http://www.linkedin.com/in/stevenleiva

It's better to try to model execution using lambda calculus.
The most dominant factor in languages like Haskell is lambda calculus.
Think through lambda calculus for a mental model.
On Thu, 24 Jun 2021 at 16:45, Steven Leiva
Wonderful question. I would love to see something like this too.
What kind of confusion are you running into with Haskell? Are they of the type error variety, or do you have a well-typed program that doesn't do what you want?
*If* it is the type error stuff, I would recommend that you give the compiler information about what you think the types are. The reason is that type information can flow from very far away places than where you are getting an error. For example, I was writing this code the other day:
*for eIdpData \ $(schoolId, districtId, tenantId) -> pure $ Right 1*
The type of for is *for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)*
In my case, I knew the following:
*t ~ Either SyncFailure* *a ~ IdpData* *f ~ WriterT Logs m* *b ~ Int*
Once I do replace type variables with concrete types / type constructors, it becomes clear that my function argument should return an *Int* in some structure, and instead I am returning an *Either a Int*. This helps me figure out the problem.
Writing out takes a lot longer than actually doing it. Anyway, the key is to provide GHC with the information you think you know; this will prevent type inference from allowing type information to flow from far away places, and the error will become clearer or at the very least more localized.
On Wed, Jun 23, 2021 at 11:42 PM Michael Turner < michael.eugene.turner@gmail.com> wrote:
When I write C, or even C++, I have a mental model of how execution will proceed.
When I write Prolog, but get confused, I run a kind of skeletal inference algorithm in my head and the confusion usually clears up. I can imagine how things are stored and what's done with them. I can see /through/ the code to the machine.
With Haskell, I still feel blind.
Has anyone summarized it all in a chart where I can look at it and think, "Ah, OK, GHC is taking this line and thinking of it THIS way"? If someone wanted to write an interpreter for Haskell, would there be a way for them to see how it would basically need to work, in one chart?
Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner@projectpersephone.org
Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone
"Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Steven Leiva 305.528.6038 leiva.steven@gmail.com http://www.linkedin.com/in/stevenleiva _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

I recently wrote a blog post which explains how expressions are evaluated: https://coot.me/posts/containers-strict-foldr.html
Best regards,
Marcin
Sent with ProtonMail Secure Email.
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Thursday, June 24th, 2021 at 05:41, Michael Turner
When I write C, or even C++, I have a mental model of how execution
will proceed.
When I write Prolog, but get confused, I run a kind of skeletal
inference algorithm in my head and the confusion usually clears up. I
can imagine how things are stored and what's done with them. I can see
/through/ the code to the machine.
With Haskell, I still feel blind.
Has anyone summarized it all in a chart where I can look at it and
think, "Ah, OK, GHC is taking this line and thinking of it THIS way"?
If someone wanted to write an interpreter for Haskell, would there be
a way for them to see how it would basically need to work, in one
chart?
Regards,
Michael Turner
Executive Director
Project Persephone
1-25-33 Takadanobaba
Shinjuku-ku Tokyo 169-0075
Mobile: +81 (90) 5203-8682
turner@projectpersephone.org
Understand - http://www.projectpersephone.org/
Volunteer - https://github.com/ProjectPersephone
"Love does not consist in gazing at each other, but in looking outward
together in the same direction." -- Antoine de Saint-Exupéry
Beginners mailing list
Beginners@haskell.org
participants (4)
-
coot@coot.me
-
Michael Turner
-
Steven Leiva
-
Tarik ÖZKANLI