Composing web part continuations in Suave.IO with F# - f#

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.

If you partially apply first and second, they become Webpart -> Webpart.
You can then use function composition:
first 1 >> second 2 <| third

Related

args[] in Main for F#

Here is some code In F# that I tried following the book Programming F# byChris Smith:
(*
Mega Hello World:
Take two command line parameters and then print
them along with the current time to the console.
*)
open System
[<EntryPoint>]
let main (args : string[]) =
if args.Length <> 2 then
failwith "Error: Expected arguments <greeting> and <thing>"
let greeting, thing = args.[0], args.[1]
let timeOfDay = DateTime.Now.ToString("hh:mm tt")
printfn "%s, %s at %s" greeting thing timeOfDay
// Program exit code
0
main(["asd","fgf"]) |> ignore
There is an error in main that says: This expression was expected to have type 'String[]' but here ahs type "a list'. But string[] is an array of string. SO I don't understand my error.
string[] is indeed an array of strings, but ["asd", "fgf"] is not - it's a list, which is why you get that error.
To create an array instead, use [|"asd"; "fgf"|] (note that, both in lists and arrays, ; is used as a separator - , creates tuples).
In addition, you can't have code after a function marked as EntryPoint. And even if you could, calling that function makes no sense as it will already be called automatically with the command line arguments - that's the point of the EntryPoint attribute.

F# incorrect type and another incorrect type in the function call

Not sure what's off about this code. I want to use this as the main function to print a string or return not enough arguments. What's incorrect about this VS15 isn't very helpful in this instance.
[<EntryPoint>]
let main argv =
if (List.length argv) >= 1 then
printfn "Hello %s" argv.[0]; 0
else
printfn "Not enough arguments"; 1
main ["Test"]
Even though you didn't specify what error you get and where it appears (please always do that when asking questions), I can see what's wrong with your code: you're treating argv as if it was a List, but a .NET program entry point must accept an argument of type Array - specifically, array of strings - string[].
If you switch out List.length for Array.length, the function will compile.
[<EntryPoint>]
let main argv =
if (Array.length argv) >= 1 then
printfn "Hello %s" argv.[0]; 0
else
printfn "Not enough arguments"; 1
Now, if you want to call this function, you would want to supply an argument that is an array, not List. In F#, the brackets are used to denote a list. If you want to denote an array, you need to use bracket-pipes instead:
main [| "Test |]
EDIT in response to comment:
Normally you wouldn't need to "call" the entry point function explicitly. Entry point is the "start" of the program, there are no other functions calling it. This is why the entry point function must be the last function in the last file of the program. If you do place any code after the entry point, the compiler will give you an error.
The way you wrote the call main ["Test"], I assumed you just wanted to execute this call in F# interactive, which is a popular way of verifying your code without building and running it. Once you are ready to compile, you should remove this call.
Finally, I'd like to point out that you're actually accessing the array twice: first to check its length, then to fetch its first item. You can do both in one step using pattern matching:
[<EntryPoint>]
let main argv =
match argv with
| [|name|] -> printfn "Hello %s" name; 0
| _ -> printfn "Not enough or too many arguments"; 1
And look: this way, the program actually became slightly more valid. If you look closer, you'll notice that your original program accepts any number of arguments, but only actually uses the first one. This is a bit "unclean", so to say. The above version using pattern matching does one better: it will take exactly as many arguments as is needed for its function, or print an error message otherwise.

How can I write an fprintfn function that opens, appends, closes the file on each write, without getting an ObjectDisposedException?

TL;DR: how to write a function like fprintfn that accesses and closes a file and behaves similar to printf family of functions, but won't throw an ObjectDisposedException on multiple arguments?
As a convenience embedded function, I found myself writing the following code, which worked for a while:
let fprintfn a b =
use handle = File.AppendText("somelogfile.log")
printfn a b |> ignore // write to stdout
fprintfn handle a b // write to logfile
// works
fprintfn "Here we are, %i years of age" 42
// throws ObjectDisposedException
fprintfn "Here we are, %i years of age in $i" 42 DateTime.Now.Year
The error is raised whether I use use or using and as soon as the number of arguments exceeds 2.
After some head-scratching, I concluded that the new fprintfn function above creates a closure as soon as I use it with more than one print format argument. Which seems to make sense to some extend, albeit a bit more hidden then in cases where you return a closure explicitly (i.e. returning an actual fun x -> something which accesses the handle variable).
Now the question is: how can I rewrite the above statement while retaining the convenience of the original fprintfn function use and syntax, without having it throw the ObjectDisposedException?
PS: A preferred way of writing the above function would be to use the following, which allows all fprintfn syntax, but that will throw the same exception already when you use a single print format argument.
let fprintfn a =
use handle = File.AppendText("somelogfile.log")
printfn a |> ignore
fprintfn handle a
fprintf "Test" // works
fprintf "Test: %i" 42 // throws ODE
You are right that fprintf creates a continuation and returns it, so that by the time you call that continuation, the file is already closed.
But you can go one level deeper and use kprintf. It lets you provide a "continuation" - i.e. a function that receives the formatted string and does whatever with it.
let fprintfn a =
let doPrint s =
use handle = File.AppendText("somelogfile.log")
printfn "%s" s
fprintfn handle "%s" s
kprintf doPrint a
And then, of course, you can simplify that a bit by using File.AppendAllText:
let fprintfn a =
let doPrint s =
File.AppendAllText("somelogfile.log", s + "\n")
printfn "%s" s
kprintf doPrint a

My F# program is trying to connect to the network and I have no network code

Basically I have been writing a small and horribly inefficient interpreter for a language of my own design for fun. Writing it in F#. The odd part is that when give it some lengthy code to interpret, like my version of a loop, like "loop true do 0" (which would translate into an infinate loop), it tries to connect to the network. I know because my firewall notices it and asks me what to do. This is not intentional, I have not a single line of network code in my program. I even changed to loop code in the interpreter as an experiment to just an eternal F# while loop, so it would just loop on forever and not do any interpreter stuff, but it had no effect.
When I say networking related stuff I am talking about connecting to one of these two addresses:
224.0.0.252
and
239.255.255.250
After googling this I found that 224.0.0.252 has something to do with LLMNR (Link Local Multicast Name Resolution) and 239.255.255.250 has something to do with SSDP (Simple Service Discovery Protocol) but I dont know what that means.
Does anyone have an idea of why my program is doing this?
EDIT:
The loop code looks like this atm (on purpose, to check if it was my code that did it or not):
and loopExec scope state cond body =
while true do ()
GNil
It tries to connect somewhere in the while loop. Before I had this:
and loopExec scope state cond body =
let myig _ = ()
while (exec scope state cond) <> GBool(false) do
myig <| exec (pushScope scope) state body
GNil
Where scope is the current scope, state is the current state, cond is the condition and body what should be evaluated as long as cond is true. myig was basically me running out of ideas of what the problem could be, so I made my own ignore function. exec executes the code in cond or body.
Its not the best code, I am aware of that.
EDIT 2:
I just inserted an eternal loop at the entrypoint of the entire program and it still did it... tested both in debug and release mode.
// Entrypoint of the program
[<EntryPoint>]
let main args =
while true do ()
// Display the greeting message thing
displayHelp()
// Prompt the user for code
Console.Write("> ");
let mutable inp = readCode()
let mutable runCode = true
let state = new Interpreter.State()
while inp.Trim() <> "#exit" do
if not (isValidLine inp) then
if runCode then
execCode state inp
else
printfn "Result: %A\n" (parseString inp)
elif inp = "#help" then
displayHelp()
printfn ""
elif inp = "#ast" then
runCode <- false
elif inp = "#run" then
runCode <- true
elif inp = "#names" then
showNames state
Console.Write("> ")
inp <- readCode()
// Ask the user to press enter before exiting
printfn "[PRESS ENTER TO EXIST]"
Console.Read() |> ignore
Environment.ExitCode

F# Code Execution Order

another noob question regarding F#.
If I have the following code...
let ExeC =
printfn "c"
3
let ExeB b =
printfn "b"
2
let ExeA =
printfn "a"
1
printfn "Example %d " ExeA
printfn "Example %d " (ExeB 1)
printfn "Example %d " ExeC
The output is as follows...
c
a
Example 1
b
Example 2
Example 3
What seems unusual here is the order that the code is executing in. In a previous question Brian mentioned something about expressions, I was hoping someone could explain this a bit more. It almost seems like the compiler is intelligently pre-executing things to calculate values... but I don't know?
ExeA and ExeC aren't functions, but single values. The compiler ensures that values initialise in the order in which they're declared in the source file, so what's happening here is:
ExeC initialises
ExeA initialises
Example 1 is printed, using ExeA's initialised value
The ExeB function is called as normal
Example 3 is printed, using ExeC's initialised value
If you want ExeA and ExeC to be truly lazy -- that is, to control when their side effects run -- you could turn them into functions that accept unit:
let ExeC () =
printfn "c"
3
let ExeB b =
printfn "b"
2
let ExeA () =
printfn "a"
1
printfn "Example %d " (ExeA ())
printfn "Example %d " (ExeB 1)
printfn "Example %d " (ExeC ())
As a follow up to Tim's answer, I thought you might appreciate some further insight into what you've stumbled upon. In your example, ExeC and ExeA take advantage of the functional style of organizing code through lexical scoping and closures. Let me demonstrate a more powerful example.
let calc n =
//...
let timesPieDiv4 =
let pie = 3.14
let pieDiv4 = pie/4.
n * pieDiv4
//...
Here again timesPieDiv4 is not a function, but does have a body which contains a series of sub calculations which are not exposed to the rest of the calc function. In a language like C#, you have two options neither of which appeals to me. The first option is to simply declare pie and pieDiv4 within the main body of calc, but then it's less clear how they are being used and you dirty your variable space. The other option is to factor those sub calculations out into a separate private helper function. But I dislike such functions, because with many it becomes hard to analyze your complex algorithms since you are constantly darting around looking up various implementation pieces. Plus it's a lot of boiler plate code and value passing. That's why F# functions are "public" by default, lexical scoping and closures allow you to hierarchically organize "private" functions and values within your public facing functions.

Resources