gluon 0.18.2

A static, type inferred programming language for application embedding
Documentation
let prelude = import! std.prelude
let io = import! std.effect.io
let { ? } = import! std.io
let string = import! std.string
let { (<>) } = import! std.prelude
let { map } = import! std.functor
let { (*>), wrap } = import! std.applicative
let { (<|>) } = import! std.alternative
let { flat_map, (>>=) } = import! std.monad
let { ? } = import! std.array
let { Result } = import! std.result
let { foldl } = import! std.foldable
let { Eff, ? } = import! std.effect
let { run_lift } = import! std.effect.lift

let http @ {
    Request, Response, HttpEffect, StatusCode,
    handle,
    empty_response,
    get,
    post,
    get_request,
    path,
    listen,
    read_chunk,
    write_response,
    fail,
    catch_error,

    status,
    method,
    uri,

    ?
} = import! std.http

let hello_world : Eff (HttpEffect r) Response =
    write_response (string.as_bytes "Hello World")
        *> (wrap { status = status.ok, .. http.response })

let echo_body request : Request -> Eff (HttpEffect r) () =
    do chunk = read_chunk request.body
    match chunk with
    | Some chunk -> write_response chunk *> echo_body request
    | None -> wrap ()

let echo : Eff (HttpEffect r) Response =
    (get_request >>= echo_body)
        *> wrap { status = status.ok, .. http.response }

let array_body request : Request -> Eff (HttpEffect r) (Array Byte) =
    do chunk = read_chunk request.body
    match chunk with
    | Some chunk ->
        do rest = array_body request
        wrap (chunk <> rest)
    | None -> wrap []

let sum : Eff (HttpEffect r) Response =
    let de @ { ? } = import! std.json.de
    do body = get_request >>= array_body
    match string.from_utf8 body with
    | Err _ ->
        seq write_response (string.as_bytes "Request contained invalid UTF-8")
        wrap { status = status.bad_request, .. http.response }
    | Ok string_body ->
        match de.deserialize string_body with
        | Ok int_array ->
            let int_array : Array Int = int_array
            let s = foldl (+) 0 int_array 
            seq write_response (string.as_bytes (show s))
            wrap { status = status.ok, .. http.response }
        | Err err ->
            seq write_response (string.as_bytes err)
            wrap { status = status.bad_request, .. http.response }


let handler : Eff (HttpEffect r) Response =
    (get *> path "/" *> hello_world)
        <|> (post *> path "/echo" *> echo)
        <|> (post *> path "/sum" *> sum)
        <|> (get *> path "/error" *> (wrap { status = status.internal_server_error, .. http.response }))

let print_error h = catch_error h (\msg -> io.println msg)

\port ->
    let action =
        seq io.println ("Opened server on port " <> show port)
        listen { port, .. http.default_listen_settings } handler
    run_lift action