Aeson

Prelude> import qualified Data.ByteString.Lazy as BSL

Prelude BSL> :t BSL.readFile

BSL.readFile :: FilePath -> IO BSL.ByteString



Reader Monad

r - is a reader which need to run and get final value from it

a - is an environment which need to share

runReader :: r -> a

Links:

Some time ago I started to learn Haskell . It's not the first time (and event not second) that I started to learn this language. Every time I met different problems with understanding different abstractions like a Monads, Arrows, Monad Transformers and etc... I think that I'm not alone with this :) But, in this time, I decided not to throw up training until I can not say: yes I can write in Haskell without pain. I started (as every time i did it) with the most popular book (for newbies) about Haskell - Learn You a Haskell and stopped at Reader monad. Spending some time I understand it (at least I think that I understand :)) and decided to share my understanding of this monad for the same newbie haskellers as me. Let's imagine simple and ubiquitous case that we have application which needs in some initial configurations. Application will get configuration form configuration file, let it be conf.js with very simple structure like this:It just has 1key. Of course it has very little resemblance with the real application configuration, but it is not important now and enough for the example. We will read it with great Aeson library from Bryan O'Sullivan and use it in our application. Let's start with reading configuration file content and decoding json.For the start we must define data type for mapping json data in it with Aeson. As you can see above, we have simple json structure withkey. So we will map this json structure to the following data type:has the same structure as our json, it has same fields: username. After data type creation we must read our configuration file with json data and decode it with aeson:Here you can see that we reading json file withfunction from. It has following type:whereis just. Read configuration file and get it's content. After getting content of configuration file usingfunction for decoding json data from it. After successful decoding we getand now we can builddata type for Reader and pass configuration file content to it.And now we come to the main point of this post. Main point of Reader monad to share read-only environment between couple of functions. Let's see how Reader declared inWe can see that it made as wrapper forfunction with typewhere:Another words we can build abstraction that will share configuration file content between different functions. Let's see how to implement it.Here we can seetype synonym for. Here(see above) will be environment which we will share between functions andreturn type. Now we write function for getting value offield from configuration file:As you can see it's pretty simple. Here is only one thing which we don't know -function.function retrieves the monad environment. Pretty simple. Now we can getin any place of our application withfunction. As you can rememberfunction has following type:Whereis a reader which need to run (getKeyOne in our case) andis environment (configuration file content in our case). Again pretty simple. We can get value ofwith: