bit-badger / inspired-by-fsharp
受 F# 对应类启发的 PHP 工具类
Requires
- php: >=8.4
Requires (Dev)
- phpoption/phpoption: ^1
- phpunit/phpunit: ^11
This package is not auto-updated.
Last update: 2024-10-01 03:11:10 UTC
README
此项目包含受 F# 对应类启发的 PHP 工具类。
v2 系列需要至少 PHP 8.4。此项目版本 1 中存在 PHP 8.2 - 8.3 的类似 API;具体内容请参阅其 README。
提供的内容
此处于早期阶段的库目前提供两个类,这两个类都旨在封装值并指示产生它们的操作的状态。Option<T>
代表可能或可能不具有值的变量。 Result<TOK, TError>
代表动作的结果;"ok" 和 "error" 状态都提供值。
Option<T> 替换 null 检查 | Result<TOK, TError> 替换基于异常的错误处理 | |
---|---|---|
创建 | ::Some(T) 用于 Some | ::OK(TOK) 用于 OK |
::None() 用于 None | ::Error(TError) 用于 Error | |
::of($value) None 如果 null | ||
查询 | ->isSome: bool | ->isOK: bool |
->isNone: bool | ->isError: bool | |
->contains(T, $strict = true): bool | ->contains(TOK, $strict = true): bool | |
->exists(callable(T): bool): bool | ->exists(callable(TOK): bool): bool | |
读取 | ->value: T | ->ok: TOK |
所有在缺少值时抛出异常 | ->error: TError | |
转换 | ->map(callable(T): TMapped): Option<TMapped> | ->map(callable(TOK): TMapped): Result<TMapped, TError> |
所有仍然是 Option 或 Result | ->mapError(callable(TError): TMapped): Result<TOK, TMapped> | |
迭代 | ->iter(callable(T): void): void | ->iter(callable(TOK): void): void |
检查 返回原始实例 | ->tap(callable(Option<T>): void): Option<T> | ->tap(callable(Result<TOK, TError>): void): Result<TOK, TError> |
继续处理 | ->bind(callable(T): Option<TBound>): Option<TBound> | ->bind(callable(TOK): Result<TBoundOK, TError>): Result<TBoundOK, TError> |
更改类型 | ->toArray(): T[] | ->toArray(): TOK[] |
->toOption(): Option<TOK> |
此外,Option<T>
还提供
->getOrDefault(T)
如果存在则返回 Some 值,如果 option 是 None,则返回给定的默认值。->getOrCall(callable(): mixed)
如果 option 是 None,则调用给定的函数。该函数可能返回一个值,也可能是void
或never
。->getOrThrow(callable(): Exception)
如果存在则返回 Some 值,如果 option 是 None,则抛出函数返回的异常。->filter(callable(T): bool)
将 Some 值与可调用函数进行比较,如果返回true
,则保持 Some;如果返回false
,则值将变为 None。->unwrap()
对于 None 选项返回null
,对于 Some 选项返回值。
最后,我们不应该忽视这个领域的一些真正酷的先验艺术——PhpOption 项目。 Option::of
识别他们的选项并正确转换,Option<T>
实例有一个 ->toPhpOption()
方法,可以将这些转换回 PhpOption 的 Some<T>
和 None
实例。来自同一团队还有一个 ResultType 项目,尽管这个项目的结果(目前)还没有任何转换方法。
灵感来源
F# 是一个在 .NET 下运行的 ML 风格语言。它拥有大多数函数式编程范式,但由于它运行在原本设计为面向对象运行时——并且可以使用和交互所有 .NET 库——因此它是一种实用的函数式编程方法。(许多其十年以上的特性已实现到最近的 C# 版本中。)
这个库也做了些实用的结构选择。例如,在 F# 中,可以像这样获取一个可选值...
let value =
Option.ofObj myVar
|> Option.map (fun it -> it.Replace("howd", "part"))
|> Option.defaultValue "There was no string"
如果 myVar
是 null
,则 value
将有 "没有字符串";如果 myVar
是 "howdy",则 value
将是 "party"。每个 Option
调用都将其选项作为最后一个参数,|>
是管道操作符;它将上一个值作为下一个操作的最后一个参数。这个库的先前版本有静态函数来模仿这一点,结果如下...
$value = Option::defaultValue('There was no string',
Option::map(fn($it) => str_replace('howd', 'part', $it),
Option::of($myVar)));
...这个顺序是从右到左(或者说是从下到上,就像它格式化那样)。通过将这些实现为实例方法,PHP 代码看起来更简洁。
$value = Option::of($myVar)
->map(fn($it) => str_replace('howd', 'part', $it))
->getOrDefault('There was no string');
如果 PHP 获得了一个管道操作符,我们将重新审视这里的大量内容(当然是以非破坏性的方式)。
想法
这个库目前具有其作者需要的特性。要提出其他建议,请通过 Fediverse 上的 @daniel@fedi.summershome.org 或 Twitter 上的 @Bit_Badger 联系 Daniel。