Purescript: express, Aff, FS together

import Control.Monad.Eff.Class (liftEff)resultJson :: Int -> { name :: String, times :: Int }
resultJson n dat =
{ name: “test”
, times: n
}
indexHandler :: forall e. Ref AppState -> Handler (err :: EXCEPTION, ref :: REF | e)
indexHandler stateRef =
let
getSt (AppState st) = st
in
do
state <- liftEff $ readRef stateRef
st <- liftEff $ pure $ getSt state
sendJson (resultJson st.count)
import Control.Monad.Eff.Class (liftEff)
import Node.FS as FS
import Node.FS.Aff as AIO
...
indexHandler :: forall e. Ref AppState -> Handler (err :: EXCEPTION, fs :: IO.FS, ref :: REF | e)
indexHandler stateRef =
let
getSt (AppState st) = st
in
do
state <- liftEff $ readRef stateRef
st <- liftEff $ pure $ getSt state
-- Handler is
HandlerM (Request -> Response -> Eff e Unit -> Aff e a)
-- So I think to myself, <- strips Aff ..., not thinking that
-- the monad decorating <- here is HandlerM (...)
-- but the type of HandlerM is more complicated than that.

fdata <- AIO.readTextFile Encoding.UTF8 “test.txt”
sendJson (resultJson st.count fdata)
import Control.Monad.Aff.Class (liftAff)
import Control.Monad.Eff.Class (liftEff)
import Node.FS as FS
import Node.FS.Aff as AIO
...indexHandler :: forall e. Ref AppState -> Handler (err :: EXCEPTION, fs :: IO.FS, ref :: REF | e)
indexHandler stateRef =
let
getSt (AppState st) = st
in
do
state <- liftEff $ readRef stateRef
st <- liftEff $ pure $ getSt state
-- The answer turned out to be easier and different from
-- what I expected: liftAff replaces liftEff in the case of
-- an Aff, or asynchronous effect. This works because
-- HandlerM is based on Aff.

fdata <- liftAff $ AIO.readTextFile Encoding.UTF8 “test.txt”
sendJson (resultJson st.count fdata)
HandlerM (Request -> Response -> Eff e Unit -> Aff e a)
HandlerM ((Request -> Response -> Eff e Unit) -> Aff e a)
(* Note that I'm using some custom wrappers, but you can see that
* shape of the result is the same: this express handler returns
* a promise that eventually ends the response. *)
app |> Express.get “/”
(fun req res nxt ->
QIO.readTextFile "utf8" “test.txt”
|> Q.handle (fun e -> toString e)
|> Q.map (Express.resEndString res)
|> Q.fin
)
-- Does something with an a
data DoSomething a = DoSomething a
instance functorHandlerM :: Functor (HandlerM e) where
map f (HandlerM h) = HandlerM \req resp nxt ->
(h req resp nxt >>= \r -> pure $ f r)

--

--

--

An old programmer learning new tricks.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Avoid ‘return’ sonar issues in JavaScript

JavaScript use case in Machine Learning Industry

Timer in angular. Small and simple.

HTML TUTORIAL FOR BEGINNERS PART 4

Upgrading DriveTribe to React 16

Visitor Pattern in TypeScript

What’s new in angular 11?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
art yerkes

art yerkes

An old programmer learning new tricks.

More from Medium

Moving into the subscription model

Reactive programming in action — part 1

scaling nodejs based micro services

scaling-microservices

TypeScript-based caching decorators