Skip to content

Instantly share code, notes, and snippets.

@ddrpa
Created January 29, 2026 09:02
Show Gist options
  • Select an option

  • Save ddrpa/68df08f9877d5f8a3952bb4d2e3c2468 to your computer and use it in GitHub Desktop.

Select an option

Save ddrpa/68df08f9877d5f8a3952bb4d2e3c2468 to your computer and use it in GitHub Desktop.
Type R for Java
package cc.ddrpa.labs.lang;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
public record R<T, E>(T value, E error) {
public static <T, E> R<T, E> ok(T value) {
return new R<>(value, null);
}
public static <T, E> R<T, E> err(E error) {
return new R<>(null, error);
}
/**
* 执行给定的 supplier,并将结果包装为 Result。
* <p>
* - 如果 supplier 成功返回值,则返回 Result.ok(value)。
* - 如果 supplier 抛出任何异常 (Throwable),则捕获异常并返回 Result.err(exception)。
* <p>
* 这允许将可能抛异常的操作转化为安全的 Result,而无需调用方使用 try/catch。
* <p>
* 示例:
* <pre>
* Result<Integer, Throwable> r1 = R.of(() -> 10 / 2);
* // r1 = Result.ok(5)
*
* Result<Integer, Throwable> r2 = R.of(() -> 10 / 0);
* // r2 = Result.err(ArithmeticException)
* </pre>
*
* @param supplier 可能抛异常并返回 T 的操作
* @param <T> 成功值类型
* @return 如果 supplier 成功执行,返回 Result.ok(value);如果抛异常,返回 Result.err(exception)
*/
public static <T> R<T, Throwable> of(Supplier<T> supplier) {
try {
return R.ok(supplier.get());
} catch (Throwable e) {
return R.err(e);
}
}
public boolean isOk() {
return error == null;
}
public boolean isErr() {
return !isOk();
}
public Optional<T> valueOpt() {
return Optional.ofNullable(value);
}
public Optional<E> errorOpt() {
return Optional.ofNullable(error);
}
/**
* 将当前 Result 的成功值应用给定函数 f 转换为新的成功值。
* 如果当前 Result 是失败值,则保持失败不变。
* <p>
* 这允许你对成功结果进行变换,同时保持失败信息不受影响。
* <p>
* 示例:
* <pre>
* Result<Integer, String> r1 = Result.ok(10);
* Result<Integer, String> r2 = r1.map(x -> x * 2);
* // r2 = Result.ok(20)
*
* Result<Integer, String> r3 = Result.err("error");
* Result<Integer, String> r4 = r3.map(x -> x * 2);
* // r4 = Result.err("error"),失败保持不变
* </pre>
*
* @param f 将成功值 T 转换为新值 U 的函数
* @param <U> 新成功值类型
* @return 转换后的 Result,如果当前 Result 失败则保持失败
*/
public <U> R<U, E> map(Function<T, U> f) {
return isOk() ? R.ok(f.apply(value)) : R.err(error);
}
/**
* 如果当前 Result 表示成功值 (isOk() == true),则将其值传入给定的函数 f,
* 并返回函数的结果。
* <p>
* 如果当前 Result 表示失败值 (isErr() == true),则直接返回原失败,不会调用函数 f。
* <p>
* 这允许你将多个可能失败的操作串联起来:每一步都可能返回失败,一旦遇到失败,后续操作不会执行。
* <p>
* 示例:
* <pre>
* Result<Integer, String> r1 = Result.ok(10);
* Result<Integer, String> r2 = r1.flatMap(x -> Result.ok(x * 2));
* // r2 = Result.ok(20)
*
* Result<Integer, String> r3 = Result.err("error");
* Result<Integer, String> r4 = r3.flatMap(x -> Result.ok(x * 2));
* // r4 = Result.err("error"),lambda 不会执行
* </pre>
*
* @param f 将成功值 T 转换为另一个 Result<U, E> 的函数
* @param <U> 新的成功值类型
* @return 如果当前 Result 成功,返回 f.apply(value) 的结果;如果当前失败,返回原失败
*/
public <U> R<U, E> flatMap(Function<T, R<U, E>> f) {
return isOk() ? f.apply(value) : R.err(error);
}
/**
* 如果当前 Result 表示失败值 (isErr() == true),则使用给定函数 f 将失败值转换为成功值。
* 如果当前 Result 已经是成功值,则保持不变。
* <p>
* 这允许你在失败时提供一个“降级值”或者默认值。
* <p>
* 示例:
* <pre>
* Result<Integer, String> r1 = Result.err("error");
* Result<Integer, String> r2 = r1.recover(e -> 0);
* // r2 = Result.ok(0)
*
* Result<Integer, String> r3 = Result.ok(10);
* Result<Integer, String> r4 = r3.recover(e -> 0);
* // r4 = Result.ok(10) ,原成功值保持不变
* </pre>
*
* @param f 将失败值 E 转换为成功值 T 的函数
* @return 如果当前 Result 成功,返回自身;如果失败,返回通过 f 转换后的成功 Result
*/
public R<T, E> recover(Function<E, T> f) {
return isOk() ? this : R.ok(f.apply(error));
}
/**
* 将当前 Result 的失败值应用给定函数 f 转换为新的失败值。
* 如果当前 Result 是成功值,则保持成功不变。
* <p>
* 这允许你在传播失败时对错误信息进行调整或包装,而不影响成功结果。
* <p>
* 示例:
* <pre>
* Result<Integer, String> r1 = Result.err("error");
* Result<Integer, Integer> r2 = r1.mapError(e -> e.length());
* // r2 = Result.err(5)
*
* Result<Integer, String> r3 = Result.ok(10);
* Result<Integer, Integer> r4 = r3.mapError(e -> e.length());
* // r4 = Result.ok(10) ,成功保持不变
* </pre>
*
* @param f 将失败值 E 转换为新失败值 F 的函数
* @param <F> 新失败值类型
* @return 转换后的 Result,如果当前 Result 成功则保持成功
*/
public <F> R<T, F> mapError(Function<E, F> f) {
return isOk() ? R.ok(value) : R.err(f.apply(error));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment