From 4393865bb75e4b89b1ea9b07c515c7d55505ad1a Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Sun, 30 Aug 2020 21:34:09 +0200 Subject: Introducing the Opinions page --- .gitignore | 3 +- site/cleopatra/theme.org | 3 +- site/index.org | 4 -- site/opinions/MonadTransformers.org | 78 +++++++++++++++++++++++++++++++++++++ site/opinions/index.org | 18 +++++++++ site/posts/MonadTransformers.org | 78 ------------------------------------- 6 files changed, 100 insertions(+), 84 deletions(-) create mode 100644 site/opinions/MonadTransformers.org create mode 100644 site/opinions/index.org delete mode 100644 site/posts/MonadTransformers.org diff --git a/.gitignore b/.gitignore index 1907ea8..678fb8b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,8 @@ site/posts/StronglySpecifiedFunctions.html site/posts/RewritingInCoq.html site/posts/LtacMetaprogramming.html site/posts/MixingLtacAndGallina.html +site/opinions/index.html +site/opinions/MonadTransformers.html site/index.html site/news/ColorlessThemes-0.2.html site/cleopatra/soupault.html @@ -50,7 +52,6 @@ site/projects/index.html site/posts/Thanks.html site/posts/DiscoveringCommonLisp.html site/posts/ExtensibleTypeSafeErrorHandling.html -site/posts/MonadTransformers.html site/posts/CleopatraV1.html site/posts/Ltac.html build/ diff --git a/site/cleopatra/theme.org b/site/cleopatra/theme.org index fe68690..296e167 100644 --- a/site/cleopatra/theme.org +++ b/site/cleopatra/theme.org @@ -74,8 +74,9 @@ noscript.parentNode.removeChild(noscript);
diff --git a/site/index.org b/site/index.org index f530c43..44af7c1 100644 --- a/site/index.org +++ b/site/index.org @@ -63,10 +63,6 @@ type system. error handling, the result is nice, type-safe API for Haskell, with a lot of GHC magic under the hood. -- [[./posts/MonadTransformers.org][Monad Transformers are a Great Abstraction]] :: - Monads are hard to get right, monad transformers are harder. Yet, they remain - a very powerful abstraction. - * Miscellaneous - [[./posts/DiscoveringCommonLisp.html][Discovering Common Lisp with ~trivial-gamekit~]] :: diff --git a/site/opinions/MonadTransformers.org b/site/opinions/MonadTransformers.org new file mode 100644 index 0000000..7296f08 --- /dev/null +++ b/site/opinions/MonadTransformers.org @@ -0,0 +1,78 @@ +#+BEGIN_EXPORT html +

Monad Transformers are a Great Abstraction

+ +

This article has originally been published on July 15, 2017.

+#+END_EXPORT + +#+OPTIONS: toc:nil + +#+BEGIN_EXPORT html +
site/opinions/MonadTransformers.org
+#+END_EXPORT + +Monads are hard to get right. I think it took me around a year of Haskelling to +feel like I understood them. The reason is, to my opinion, there is not such +thing as /the/ Monad. It is even the contrary. When someone asks me how I would +define Monads in only a few words, [[https://techn.ical.ist/@lthms/590439][I say Monad is a convenient formalism to +chain specific computations]]. Once I’ve got that, I started noticing “monadic +construction” everywhere, from the Rust ~?~ operator to the [[https://blog.drewolson.org/elixirs-secret-weapon/][Elixir ~with~ +keyword]]. + +Haskell often uses another concept above Monads: Monad Transformers. This allows +you to work not only with /one/ Monad, but rather a stack. Each Monad brings its +own properties and you can mix them into your very own one. That you can’t have +in Rust or Elixir, but it works great in Haskell. Unfortunately, it is not an +easy concept and it can be hard to understand. This article is not an attempt to +do so, but rather a postmortem review of one situation where I found them +extremely useful. If you think you have understood how they work, but don’t see +the point yet, you might find here a beginning of answer. + +Recently, I ran into a very good example of why Monad Transformers worth it. I +have been working on a project called [[https://github.com/ogma-project][ogma]] for a couple years now. In a +nutshell, I want to build “a tool” to visualize in time and space a +storytelling. We are not here just yet, but in the meantime I have wrote a +software called ~celtchar~ to build a novel from a list of files. One of its +newest feature is the choice of language, and by extension, the typographic +rules. This information is read from a configuration file very early in the +program flow. Unfortunately, its use comes much later, after several function +calls. + +In Haskell, you deal with that kind of challenges by relying on the Reader +Monad. It carries an environment in a transparent way. The only thing is, I was +already using the State Monad to carry the computation result. But that’s not an +issue with the Monad Transformers. + +#+BEGIN_SRC diff +-type Builder = StateT Text IO ++type Builder = StateT Text (ReaderT Language IO) + +#+END_SRC + +As you may have already understood, I wasn't using the “raw” ~State~ Monad, but +rather the transformer version ~StateT~. The underlying Monad was ~IO~, because +I needed to be able to read some files from the filesystem. By replacing ~IO~ by +~ReaderT Language IO~, I basically fixed my “carry the variable to the correct +function call easily” problem. + +Retrieving the chosen language is as simple as: + +#+BEGIN_SRC haskell +getLanguage :: Builder Language +getLanguage = lift ask +#+END_SRC + +And that was basically it. The complete [[https://github.com/ogma-project/celtchar/commit/65fbda8159d21d681e4e711a37fa3f05b49e6cdd][commit]] can be found on Github. + +Now, my point is not that Monad Transformers are the ultimate beast we will have +to tame once and then everything will be shiny and easy. There are a lot of +other way to achieve what I did with my ~Builder~ stack. For instance, in an +OO language, I probably would have to add a new class member to my ~Builder~ +class and I would have done basically the same thing. + +However, there is something I really like about this approach: the ~Builder~ +type definition gives you a lot of useful information already. Both the ~State~ +and ~Reader~ Monads have a well established semantics most Haskellers will +understand in a glance. A bit of documentation won’t hurt, but I suspect it is +not as necessary as one could expect. Moreover, the presence of the ~IO~ Monad +tells everyone using the ~Builder~ Monad might cause I/O. diff --git a/site/opinions/index.org b/site/opinions/index.org new file mode 100644 index 0000000..0be267e --- /dev/null +++ b/site/opinions/index.org @@ -0,0 +1,18 @@ +#+options: num:nil + +#+BEGIN_EXPORT html +

Opinions

+#+END_EXPORT + +I may have some opinions on some topics, and sometimes I may want to share +them. However, I strongly believe facts and opinions are two differents things, +and even though I do not intend to write plain wrong facts, I prefer to keep two +separate indexes. + +I would encourage you to use your critical mind while reading these write-ups. + +** 2017 + +- [[./MonadTransformers.org][Monad Transformers are a Great Abstraction]] :: + Monads are hard to get right, monad transformers are harder. Yet, they remain + a very powerful abstraction. diff --git a/site/posts/MonadTransformers.org b/site/posts/MonadTransformers.org deleted file mode 100644 index b2bd2ca..0000000 --- a/site/posts/MonadTransformers.org +++ /dev/null @@ -1,78 +0,0 @@ -#+BEGIN_EXPORT html -

Monad Transformers are a Great Abstraction

- -

This article has originally been published on July 15, 2017.

-#+END_EXPORT - -#+OPTIONS: toc:nil - -#+BEGIN_EXPORT html -
site/posts/MonadTransformers.org
-#+END_EXPORT - -Monads are hard to get right. I think it took me around a year of Haskelling to -feel like I understood them. The reason is, to my opinion, there is not such -thing as /the/ Monad. It is even the contrary. When someone asks me how I would -define Monads in only a few words, [[https://techn.ical.ist/@lthms/590439][I say Monad is a convenient formalism to -chain specific computations]]. Once I’ve got that, I started noticing “monadic -construction” everywhere, from the Rust ~?~ operator to the [[https://blog.drewolson.org/elixirs-secret-weapon/][Elixir ~with~ -keyword]]. - -Haskell often uses another concept above Monads: Monad Transformers. This allows -you to work not only with /one/ Monad, but rather a stack. Each Monad brings its -own properties and you can mix them into your very own one. That you can’t have -in Rust or Elixir, but it works great in Haskell. Unfortunately, it is not an -easy concept and it can be hard to understand. This article is not an attempt to -do so, but rather a postmortem review of one situation where I found them -extremely useful. If you think you have understood how they work, but don’t see -the point yet, you might find here a beginning of answer. - -Recently, I ran into a very good example of why Monad Transformers worth it. I -have been working on a project called [[https://github.com/ogma-project][ogma]] for a couple years now. In a -nutshell, I want to build “a tool” to visualize in time and space a -storytelling. We are not here just yet, but in the meantime I have wrote a -software called ~celtchar~ to build a novel from a list of files. One of its -newest feature is the choice of language, and by extension, the typographic -rules. This information is read from a configuration file very early in the -program flow. Unfortunately, its use comes much later, after several function -calls. - -In Haskell, you deal with that kind of challenges by relying on the Reader -Monad. It carries an environment in a transparent way. The only thing is, I was -already using the State Monad to carry the computation result. But that’s not an -issue with the Monad Transformers. - -#+BEGIN_SRC diff --type Builder = StateT Text IO -+type Builder = StateT Text (ReaderT Language IO) - -#+END_SRC - -As you may have already understood, I wasn't using the “raw” ~State~ Monad, but -rather the transformer version ~StateT~. The underlying Monad was ~IO~, because -I needed to be able to read some files from the filesystem. By replacing ~IO~ by -~ReaderT Language IO~, I basically fixed my “carry the variable to the correct -function call easily” problem. - -Retrieving the chosen language is as simple as: - -#+BEGIN_SRC haskell -getLanguage :: Builder Language -getLanguage = lift ask -#+END_SRC - -And that was basically it. The complete [[https://github.com/ogma-project/celtchar/commit/65fbda8159d21d681e4e711a37fa3f05b49e6cdd][commit]] can be found on Github. - -Now, my point is not that Monad Transformers are the ultimate beast we will have -to tame once and then everything will be shiny and easy. There are a lot of -other way to achieve what I did with my ~Builder~ stack. For instance, in an -OO language, I probably would have to add a new class member to my ~Builder~ -class and I would have done basically the same thing. - -However, there is something I really like about this approach: the ~Builder~ -type definition gives you a lot of useful information already. Both the ~State~ -and ~Reader~ Monads have a well established semantics most Haskellers will -understand in a glance. A bit of documentation won’t hurt, but I suspect it is -not as necessary as one could expect. Moreover, the presence of the ~IO~ Monad -tells everyone using the ~Builder~ Monad might cause I/O. -- cgit v1.2.3