2

Using Suave.IO, I have the following monolithic WebPart:

let success msg =
    Successful.OK <| sprintf "Success: %s" msg

let error msg =
    Successful.OK <| sprintf "Error: %s" msg

let monolith arg1 arg2 =
    if doFirstThing arg1 then
        if doSecondThing arg2 then
            success "Everything worked"
        else
            error "Second thing failed"
    else
        error "First thing failed"

Being a good functional programmer, I'd like to break the monolith into its distinct components. What is the best way to do this?

My first attempt uses "continuation" web parts, like this:

let first arg cont =
    if doFirstThing arg then cont
    else error "First thing failed"

let second arg cont =
    if doSecondThing arg then cont
    else error "Secong thing failed"

let third : WebPart =
    success "Everything worked"

However, composing these together looks ugly because of the nested invocations:

first 1 (second 2 third)

Is there a better way to do this? Specifically, is there an operator I can insert between each component in order to compose them elegantly? Something like:

first 1 >?> second 2 >?> third

My intuition says something like this should work, but I don't know enough category theory to do it correctly. Any insight would be welcome.

4

1 回答 1

1

If you partially apply first and second, they become Webpart -> Webpart.

You can then use function composition:

first 1 >> second 2 <| third
于 2019-01-05T13:26:09.023 回答