Cleaning Up Old F#
I decided to lightly brush up an old F# script I worked on over a year ago more toward the beginning of my F# and functional programming studies. I’m glad kept it, as it’s more evidence of how I’m slowly progressing. (There’s nothing like being embarrassed by your old own code. 😄)
For example, check out this block I wrote when I apparently first learned about computation expressions (CEs):
result {
let! args = checkArgCount rawArgs
let! args' = checkStyleName args
let! args'' = checkInputLength args'
let! args''' = checkInputChars args''
return args'''
}
That code works, of course, but it’s needlessly verbose and prone to errors due to the similar variable names.
I immediately realized that, under the hood, there was just some monadic binding of the Results going on, so I rewrote the code like this:
rawArgs
|> checkArgCount
>>= checkStyleName
>>= checkInputLength
>>= checkInputChars
Terser, clearer, and safer. I love it.
(Not that CEs aren’t great too, of course. Just not here.)
For practice, I tried out function composition too. Admittedly, I first tried >> out of habit, though of course it didn’t work. I immediately realized what I actually needed to combine monadic functions was the Kleisli composition operator:
// Inline version
rawArgs
|> (checkArgCount >=> checkStyleName >=> checkInputLength >=> checkInputChars)
// Bound version, which is likely more practical.
let validate =
checkArgCount
>=> checkStyleName
>=> checkInputLength
>=> checkInputChars
validate rawArgs
I think it’s only the second time I’ve actually used this operator, so I’m glad I recalled it.