using System.Collections.Generic;
public static void Main(string[] args)
var nonEmptyTitle = "The Old Man and the Sea";
var nonEmptyAuthor = "Ernest Hemingway";
var bookController = new BookController();
Console.WriteLine(string.Format("empty title + empty author + GetBookFunctional = {0}", bookController.GetBookFunctional(string.Empty, string.Empty)));
Console.WriteLine(string.Format("empty title + empty author + GetBookImperative = {0}", bookController.GetBookImperative(string.Empty, string.Empty)));
Console.WriteLine(string.Format("empty title + empty author + GetBookImperativeSpecial = {0}", bookController.GetBookImperativeWithoutElses(string.Empty, string.Empty)));
Console.WriteLine(string.Format("empty title + non empty author + GetBookFunctional = {0}", bookController.GetBookFunctional(string.Empty, nonEmptyAuthor)));
Console.WriteLine(string.Format("empty title + non empty author + GetBookImperative = {0}", bookController.GetBookImperative(string.Empty, nonEmptyAuthor)));
Console.WriteLine(string.Format("empty title + non empty author + GetBookImperativeSpecial = {0}", bookController.GetBookImperativeWithoutElses(string.Empty, nonEmptyAuthor)));
Console.WriteLine(string.Format("non empty title + empty author + GetBookFunctional = {0}", bookController.GetBookFunctional(nonEmptyTitle, string.Empty)));
Console.WriteLine(string.Format("non empty title + empty author + GetBookImperative = {0}", bookController.GetBookImperative(nonEmptyTitle, string.Empty)));
Console.WriteLine(string.Format("non empty title + empty author + GetBookImperativeSpecial = {0}", bookController.GetBookImperativeWithoutElses(nonEmptyTitle, string.Empty)));
Console.WriteLine(string.Format("non empty title + non empty author + GetBookFunctional = {0}", bookController.GetBookFunctional(nonEmptyTitle, nonEmptyAuthor)));
Console.WriteLine(string.Format("non empty title + non empty author + GetBookImperative = {0}", bookController.GetBookImperative(nonEmptyTitle, nonEmptyAuthor)));
Console.WriteLine(string.Format("non empty title + non empty author + GetBookImperativeSpecial = {0}", bookController.GetBookImperativeWithoutElses(nonEmptyTitle, nonEmptyAuthor)));
internal class BookController : ApiController
public IHttpActionResult GetBookFunctional(string title, string author)
var titleOption = NonEmptyString.Create(title);
var authorOption = NonEmptyString.Create(author);
var result = titleOption.Match(
t => authorOption.Match<IHttpActionResult>(
a => new Ok(BookService.GetBook(t, a)),
() => new BadRequest("Invalid author")),
() => authorOption.Match(
a => new BadRequest("Invalid title"),
() => new BadRequest(string.Format("Invalid title{0}Invalid author", Environment.NewLine))));
public IHttpActionResult GetBookImperative(string title, string author)
var titleOption = NonEmptyString.Create(title);
var authorOption = NonEmptyString.Create(author);
IHttpActionResult result;
result = new Ok(BookService.GetBook(titleOption.SingleOrDefault(), authorOption.SingleOrDefault()));
result = new BadRequest("Invalid author");
result = new BadRequest("Invalid title");
result = new BadRequest(string.Format("Invalid title{0}Invalid author", Environment.NewLine));
public IHttpActionResult GetBookImperativeWithoutElses(string title, string author)
var titleOption = NonEmptyString.Create(title);
var authorOption = NonEmptyString.Create(author);
var reasons = new List<string>();
reasons.Add("Invalid title");
reasons.Add("Invalid author");
IHttpActionResult result;
result = new BadRequest(string.Join(Environment.NewLine, reasons));
result = new Ok(new Book());
internal class NonEmptyString
private NonEmptyString(string input)
internal static Option<NonEmptyString> Create(string input)
if (string.IsNullOrWhiteSpace(input))
return new Option<NonEmptyString>();
return new Option<NonEmptyString>(new NonEmptyString(input));
public bool IsNone { get; internal set; }
public bool IsSome { get; internal set; }
internal TResult Match<TResult>(Func<T, TResult> p1, Func<TResult> p2)
internal T SingleOrDefault()
internal class Ok : IHttpActionResult
public static implicit operator string(Ok ok)
internal class BadRequest : IHttpActionResult
public BadRequest(string v)
public static implicit operator string(BadRequest badRequest)
internal class ApiController
public interface IHttpActionResult
internal class BookService
internal static Book GetBook(NonEmptyString title, NonEmptyString author)