CARVIEW |
Select Language
HTTP/2 200
date: Fri, 25 Jul 2025 10:24:48 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
etag: W/"3458311247c03290b4ce1217ec32c741"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=MLMZsE6B3ocBaaOiSo4lyFphgcLO2SewdWm66LRpMy7WczupG7zXgDIH2bcwUFqtLIqtMEkH02n3SbgMGkZWD4ZCPLlvU6NDJAe0DYhtccLkRK8%2BlA03tTXJtlTI6KNNliDljl8W8A3KjyUjBqoLEvoBu%2Fy3tQpPy57Delv7ZjbxLKghn28R7bPDmc02WdLtbNo%2BTjoqj2SjkXahFW%2BY1c2sfA2dO25XwiqjoTJIRM9DyjakAJe4o16pQm5jPZxtm%2BdIRUTFW4vYfaR%2BdA6XGw%3D%3D--RrYz2gGywfTcv4Zs--tflEqydxjSuVayl9e5REOQ%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.694136340.1753439087; Path=/; Domain=github.com; Expires=Sat, 25 Jul 2026 10:24:47 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Sat, 25 Jul 2026 10:24:47 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: B89C:DBBD4:732BCB:885BC5:68835B6F
GitHub - npryce/maybe-java: A Maybe type for Java
Skip to content
Navigation Menu
{{ message }}
-
Notifications
You must be signed in to change notification settings - Fork 18
A Maybe type for Java
License
npryce/maybe-java
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
The aim of the Maybe type is to avoid using 'null' references. A Maybe<T> represents a possibly non-existent value of type T. The Maybe type makes it impossible (without deliberate effort to circumvent the API) to use the value when it does not exist. A Maybe<T> is either unknown(), in which case a known value does not exist, or definitely(v), in which case the value is known to be v. A Maybe<T> is iterable, which means you can use it with the for statement to extract a value and do something with it only if there is a value. class Customer { public Maybe<String> emailAddress() { ... } ... } for (String emailAddress : aCustomer.emailAddress()) { sendEmailTo(emailAddress); } Maybe<T> being iterable really comes into its own when combined with the Guava (previously google-collections) library, which has useful functions for working with iterables. You can then work in terms of entire collections of things that might or might not exist, without having to test for the existence of each one. For example, if I have a collection of 'maybe' email addresses, some of which might exist and some might not: Iterable<Maybe<String>> maybeEmailAddresses = ... I can get a set of only the actual email addresses in a single expression: Set<String> actualEmailAddresses = newHashSet(concat(maybeEmailAddresses)); The newHashSet and concat functions are defined by Guava. Concat creates an Iterable<T> from an Iterable<Iterable<T>>, concatenating the elements of each sequence into a single sequence. Because unknown() is an empty iterable, the concatenated iterable only returns the definite values. More likely, I have an iterable collection of Customers. Using a Function, I can write a single expression to get the email addresses of all customers who have an email address: Here's a function to map a customer to its 'maybe' email address: Function<Customer,Maybe<String>> toEmailAddress = new Function<Customer, Maybe<String>>() { public Maybe<String> apply(Customer c) { return c.emailAddress(); } }; And here's how to use it to get all the email addresses that my customers have, so I can send them product announcements: Set<String> emailAddresses = newHashSet( concat(transform(customers, toEmailAddress))); If I just want to send emails, I don't need the hash set: for (String emailAddress : concat(transform(customers, toEmailAddress))) { sendEmailTo(emailAddress); } The name "concat" is a bit obscure, so I'd probably define an alias named, for example, "definite", to make the code more readable at the point of use. And the Function definition is a bit clunky, but Java doesn't have (and doesn't look likely to get) a clean syntax for referring to existing functions. That's not to say that Maybe doesn't have useful methods to work with individual instances. For example, the otherwise method: T otherwise(T defaultValue); will return the Maybe's value if it is known and the defaultValue if it is not. E.g. assertThat(unknown().otherwise(""), equalTo("")); assertThat(definitely("foo").otherwise(""), equalTo("foo")); Otherwise is overloaded to take a Maybe<T> as a default: Maybe<T> otherwise(Maybe<T> maybeDefaultValue); which lets you chain otherwise expressions: assertThat(unknown().otherwise(definitely("X")).otherwise(""), equalTo("X")); Maybe also has a method that uses a function to map a Maybe<T> to a Maybe<U> <U> Maybe<U> to(Function<T,U> mapping); which would transform unknown() to unknown(), otherwise apply the function to the definite value and return the result wrapped in a Maybe. Similarly there is a query method that takes a Predicate<T> and maps a Maybe<T> to a Maybe<Boolean>. All of which API calls make it impossible (without deliberate effort) to try to get the value of nothing.
About
A Maybe type for Java
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published
You can’t perform that action at this time.