Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save miklund/9be0114022b706b48bd9 to your computer and use it in GitHub Desktop.
Save miklund/9be0114022b706b48bd9 to your computer and use it in GitHub Desktop.
2011-06-15 Dealing with dependencies in functional programming
# Title: Dealing with dependencies in functional programming
# Author: Mikael Lundin
# Link: http://blog.mikaellundin.name/2011/06/15/dealing-with-dependencies-in-functional-programming.html
// Model object
type Person = { Name : string; BirthDate : System.DateTime }
// age: get the age of a person from name
// string -> (string -> Person) -> int
let age name (fn_getPerson : string -> Person) =
// Get birthdate from dependency
let birthDate = (fn_getPerson name).BirthDate
// Calculate
(DateTime.Now - birthDate).Days / 365
age "Mikael Lundin" DataAccess.GetPerson
// or maybe
DataAccess.GetPerson |> age "Mikael Lundin"
age "Mikael" DataAccess.GetPerson
// this also works
DataAccess.GetPerson |> age "Mikael"
let authenticate username password : ((unit -> seq<User>) -> bool) =
(fun (getUsers : unit -> seq<User>) ->
getUsers() |> Seq.exists
(fun user -> user.UserName = username && user.Password = password)
(authenticate "mlu" "secret") (new UserRepository()).GetUsers
public interface IUserRepository
{
IEnumerable<User> GetUsers();
}
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
let authenticate username password (rep : IUserRepository) =
rep.GetUsers() |> Seq.exists (fun u -> u.UserName = username && u.Password = password)
// Dependency through partial function
let age name : ((string -> Person) -> int) =
// Return a function
(fun (getPerson : string -> Person) ->
// Get birthdate
let birthDate = getPerson(name).BirthDate
// Return age
(DateTime.Now - birthDate).Days / 365
)
open Xunit
open Swensen.Unquote
[<Fact>]
let ``send dependency into the function as an argument`` () =
// Setup: In our test we return a Person directly
let dependency (s : string) = { Name = s; BirthDate = new DateTime(1982, 7, 15) }
// Assert
test <@ 29 = age "Mikael" dependency @>
[<Fact>]
let ``using a partial function result to insert the dependency to`` () =
// Setup: Our dependency is called on the function result
let dependency s = { Name = s; BirthDate = new DateTime(1982, 7, 15) }
// Assert
test <@ 28 = (age "Mikael") dependency @>
[<Fact>]
let ``using an interface as dependency`` () =
// GetUsers() result
let users = [| new User(UserName = "mlu", Password = "secret") |]
// Fake repository
let repository = {
new IUserRepository with
member x.GetUsers() = users |> Seq.ofArray
}
// Assert
test <@ true = authenticate "mlu" "secret" repository @>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment