<S, A>(
getResult: (s: S) => Result.Result<A, string>,
set: (a: A, s: S) => Result.Result<S, string>
): Optional<S, A>Creates an Optional from a fallible getter and a fallible setter.
When to use
Use when you need an optic for a focus that may be missing on read and may reject updates on write.
Details
getResultshould returnResult.fail(message)on mismatch.setshould returnResult.fail(message)when the update cannot be applied.
Example (Accessing record keys safely)
import { Optic, Result } from "effect"
const atKey = (key: string) =>
Optic.makeOptional<Record<string, number>, number>(
(s) =>
Object.hasOwn(s, key)
? Result.succeed(s[key])
: Result.fail(`Key "${key}" not found`),
(a, s) =>
Object.hasOwn(s, key)
? Result.succeed({ ...s, [key]: a })
: Result.fail(`Key "${key}" not found`)
)
console.log(Result.isSuccess(atKey("x").getResult({ x: 1 })))
// Output: trueexport function function makeOptional<S, A>(
getResult: (s: S) => Result.Result<A, string>,
set: (a: A, s: S) => Result.Result<S, string>
): Optional<S, A>
Creates an
Optional
from a fallible getter and a fallible setter.
When to use
Use when you need an optic for a focus that may be missing on read and may
reject updates on write.
Details
getResult should return Result.fail(message) on mismatch.
set should return Result.fail(message) when the update cannot be
applied.
Example (Accessing record keys safely)
import { Optic, Result } from "effect"
const atKey = (key: string) =>
Optic.makeOptional<Record<string, number>, number>(
(s) =>
Object.hasOwn(s, key)
? Result.succeed(s[key])
: Result.fail(`Key "${key}" not found`),
(a, s) =>
Object.hasOwn(s, key)
? Result.succeed({ ...s, [key]: a })
: Result.fail(`Key "${key}" not found`)
)
console.log(Result.isSuccess(atKey("x").getResult({ x: 1 })))
// Output: true
makeOptional<function (type parameter) S in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>S, function (type parameter) A in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>A>(
getResult: (s: S) => Result.Result<A, string>getResult: (s: Ss: function (type parameter) S in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>S) => import ResultResult.type Result<A, E = never> = Result.Success<A, E> | Result.Failure<A, E>A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed
/
fail
to construct
- Use
match
to fold both branches
- Use
isSuccess
/
isFailure
to narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)
const failure = Result.fail("something went wrong")
const message = Result.match(success, {
onSuccess: (value) => `Success: ${value}`,
onFailure: (error) => `Error: ${error}`
})
console.log(message)
// Output: "Success: 42"
Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// number
type A = Result.Result.Success<R>
// string
type E = Result.Result.Failure<R>
Result<function (type parameter) A in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>A, string>,
set: (a: A, s: S) => Result.Result<S, string>set: (a: Aa: function (type parameter) A in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>A, s: Ss: function (type parameter) S in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>S) => import ResultResult.type Result<A, E = never> = Result.Success<A, E> | Result.Failure<A, E>A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed
/
fail
to construct
- Use
match
to fold both branches
- Use
isSuccess
/
isFailure
to narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)
const failure = Result.fail("something went wrong")
const message = Result.match(success, {
onSuccess: (value) => `Success: ${value}`,
onFailure: (error) => `Error: ${error}`
})
console.log(message)
// Output: "Success: 42"
Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// number
type A = Result.Result.Success<R>
// string
type E = Result.Result.Failure<R>
Result<function (type parameter) S in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>S, string>
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>S, function (type parameter) A in makeOptional<S, A>(getResult: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): Optional<S, A>A> {
return function make(node: Node): anymake(new constructor OptionalNode<S, A>(get: (s: S) => Result.Result<A, string>, set: (a: A, s: S) => Result.Result<S, string>): OptionalNode<S, A>OptionalNode(getResult: (s: S) => Result.Result<A, string>getResult, set: (a: A, s: S) => Result.Result<S, string>set))
}