Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
forked from svoisen/SVMaybe

A Maybe monad implementation for Objective-C

License

Notifications You must be signed in to change notification settings

OCForks/SVMaybe

Open more actions menu
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
18 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SVMaybe

A simple Maybe monad implementation in Objective-C.

Why Bother?

If you already know about Maybe from languages like Haskell, and you're familiar with Objective-C, you may be asking: "Why bother?" In Objective-C, sending a message to nil returns nil, so with a category on NSObject that adds a binding method like ifNotNil or Haskell's >>= operator, we already have Maybe monad functionality. Nothing more is necessary. But if we want more sophisticated binding functionality like that described below, this won't suffice. In that case, we need a "smarter" nil, which is what SVMaybe provides.

Overview

SVMaybe provides the following:

  1. An elegant solution to the common problem of nested nil checks in Objective-C code.
  2. Custom definitions of what is meant by "nothing" on a per-class basis ("semantic nil").

If you've ever found yourself writing something tedious like this:

NSDictionary *person = @{@"name":@"Homer Simpson", @"address":@{@"street":@"123 Fake St", @"city":@"Springfield"}};
NSString *cityString;

if (person)
{
    NSDictionary *address = (NSDictionary *)[person objectForKey:@"address"];
    if (address)
    {
        NSString *city = (NSString *)[address objectForKey:@"city"];
        if (city)
        {
            cityString = city;
        }
        else
        {
            cityString = @"No city."
        }
    }
    else
    {
        cityString = @"No address.";
    }
}
else
{
    cityString = @"No person.";
}

SVMaybe allows you to more concisely and declaratively provide the same solution:

NSDictionary *person = @{@"name":@"Homer Simpson", @"address":@{@"street":@"123 Fake St", @"city":@"Springfield"}};
NSString *cityString = [[[Maybe(person) whenNothing:Maybe(@"No person.") else:MapMaybe(person, [person objectForKey:@"address"])]
                                        whenNothing:Maybe(@"No address.")] else:MapMaybe(address, [address objectForKey:@"city"])]
                                        whenNothing:Maybe(@"No city.")] justValue];

It also allows you to move beyond simple nil checks by offering run-time redefinition of what is meant by "nothing" on a per-class basis. For instance, in the above example suppose that empty strings should also be considered "nothing." Here's the re-definition:

[NSString defineNothing:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    return [(NSString *)evaluatedObject length] == 0;
}]];

Given this re-definition, if any of the strings in the above example were empty (or nil), the monad binding would short to nothing and return the appropriate default string wrapped in a SVMaybe.

Creating Maybes

Use the provided macros:

Maybe(@"foo");
Maybe(nil); // Equals Nothing
Nothing;

Or a static method:

[SVMaybe maybe:@"foo"];
[SVMaybe maybe:nil]; // Equals [SVMaybe nothing]
[SVMaybe nothing];

Getting Values

To get the value of a maybe:

[Maybe(@"foo") justValue] // "foo"
[Nothing justValue] // Throws an exception!

Binding and Chaining

SVMaybe offers a few other chaining options in addition to whenNothing:else described above:

  • andMaybe: Binds multiple maybe values together, returning the last bound maybe. If any maybe is "nothing," the binding shorts and returns "nothing." (Equivalent to >> in Haskell.)

  • whenSomething: Binds and maps multiple maybes together using the provided block. If any maybe is "nothing," the binding shorts and returns "nothing." (Equivalent to >>= in Haskell.)

  • whenNothing: Same as whenNothing:else: but without the else block. Returns self if not nothing.

About

A Maybe monad implementation for Objective-C

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Objective-C 100.0%
Morty Proxy This is a proxified and sanitized view of the page, visit original site.