Skip to content

Instantly share code, notes, and snippets.

@jovaneyck
Last active December 8, 2015 10:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jovaneyck/dc66da9fb2d52ccdbc9f to your computer and use it in GitHub Desktop.
Save jovaneyck/dc66da9fb2d52ccdbc9f to your computer and use it in GitHub Desktop.
How to write this in idiomatic F#?
let isValid input =
input
|> parse
/*smelly and doesn't scale, what's the F# way of combining predicates?*/
|> (fun p -> predicate1 p && predicate2 p)
@swlaschin
Copy link

You can easily write helper functions:

/// Combine two predicates
let addPred predicate1 predicate2 = 
    fun p -> predicate1 p && predicate2 p

/// Combine a list of predicates
let combinePred aListOfPred = 
    aListOfPred |> List.reduce addPred

so your code becomes:

// some predicates
let isEven x = (x%2 = 0)
let isFizz x = (x%3 = 0)
let isBuzz x = (x%5 = 0)

// a validation function
let isValid input = 
    input 
    |> addPred isEven isFizz

// test
[1..30] |> List.filter isValid

let isValid2 input = 
    let megaPred = combinePred [isEven;isFizz;isBuzz]
    input 
    |> megaPred 

// test
[1..30] |> List.filter isValid2

If you are doing input validation though, I suggest you try avoid booleans if you can, and think about transformation oriented approaches. That is, taking an input and transforming it to either a success (with associated data), or a a failure (with associated error messages). I have a talk about this approach that might be useful: http://fsharpforfunandprofit.com/rop/

Cheers!

@jovaneyck
Copy link
Author

Ahh, I love the smell of idiomatic F# in the morning!
Thanks for the pointers!

I've watched your ROP talk before but thought it'd be a tad too much to just solve the adventofcode problems. Just give me a few more weeks with F# and I'll get there :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment