Skip to content

Instantly share code, notes, and snippets.

@ColinEberhardt
Created March 20, 2015 08:14
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ColinEberhardt/b4bf4e4566ffa88afcda to your computer and use it in GitHub Desktop.
Save ColinEberhardt/b4bf4e4566ffa88afcda to your computer and use it in GitHub Desktop.
Pipe forward operator and curried free functions = fluent interface
// meet Stringy - a simple string type with a fluent interface
struct Stringy {
let content: String
init(_ content: String) {
self.content = content
}
func append(appendage: Stringy) -> Stringy {
return Stringy(self.content + " " + appendage.content)
}
func printMe() {
println(content)
}
}
//////////////////////////////////////////////////////////////////////
// Stringy in action ...
var greeting = Stringy("Hi")
greeting.append(Stringy("how"))
.append(Stringy("are"))
.append(Stringy("you?"))
.printMe() // => "Hi how are you?"
// A lovely fluent interface!
//////////////////////////////////////////////////////////////////////
// Now what append and printMe were 'free functions'?
func appendFreeFunction(a: Stringy, b: Stringy) -> Stringy {
return Stringy(a.content + " " + b.content)
}
func printMe(a: Stringy) {
a.printMe()
}
// Stringy with free functions in action ...
printMe(
appendFreeFunction(
appendFreeFunction(
appendFreeFunction(greeting, Stringy("how")), Stringy("are")), Stringy("you?")))
// => "Hi how are you?"
// Yuck - we no longer have the fluent interface, with a real mess of brackets
//////////////////////////////////////////////////////////////////////
// Pipe forward
// modify the free functions, turnign them into curried functions
func appendCurriedFreeFunction(a: Stringy)(b: Stringy) -> Stringy {
return Stringy(b.content + " " + a.content)
}
// and define a pipe forward operator
infix operator |> { associativity left }
func |><X> (stringy: Stringy, transform: Stringy -> X) -> X {
return transform(stringy)
}
// we now have free functions AND a fluent interface
greeting
|> appendCurriedFreeFunction(Stringy("how"))
|> appendCurriedFreeFunction(Stringy("are"))
|> appendCurriedFreeFunction(Stringy("you?"))
|> printMe // => "Hi how are you?"
@chrishulbert
Copy link

Mind blown. This is epic. Thanks for taking it step-by-step!

@schickling
Copy link

👍

@andrelevi
Copy link

Thank you for this!

@LawrenceHan
Copy link

HOLY S**T!

@lforme
Copy link

lforme commented Apr 12, 2016

👍

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