Effect 3.9 (Release)
Effect 3.9 has been released! This release includes a number of new features and improvements. Here's a summary of what's new:
Effect.Service
To make the creation of services in Effect easier, the Effect.Service
api has been introduced.
It allows you to define both a Context.Tag
and a Layer
for a service in one pass, optionally giving you
the ability to provide any dependencies at the same time.
typescript
import { FileSystem } from "@effect/platform"import { NodeFileSystem } from "@effect/platform-node"import type { Layer } from "effect"import * as Effect from "effect/Effect"export class Cache extends Effect.Service<Cache>()("app/Cache", {// define how to create the service// You can also use the "scoped", "sync" or "succeed" keys to create your serviceeffect: Effect.gen(function* () {const fs = yield* FileSystem.FileSystemconst lookup = (key: string) => fs.readFileString(`cache/${key}`)return { lookup } as const}),// provide dependenciesdependencies: [NodeFileSystem.layer]}) {}// Layer for use in the applicationconst layer: Layer.Layer<Cache> = Cache.Default// Layer without dependencies providedconst layerNoDeps: Layer.Layer<Cache, never, FileSystem.FileSystem> =Cache.DefaultWithoutDependencies// `Cache` type also represents the service itselfdeclare const cache: Cachecache.lookup("foo")
typescript
import { FileSystem } from "@effect/platform"import { NodeFileSystem } from "@effect/platform-node"import type { Layer } from "effect"import * as Effect from "effect/Effect"export class Cache extends Effect.Service<Cache>()("app/Cache", {// define how to create the service// You can also use the "scoped", "sync" or "succeed" keys to create your serviceeffect: Effect.gen(function* () {const fs = yield* FileSystem.FileSystemconst lookup = (key: string) => fs.readFileString(`cache/${key}`)return { lookup } as const}),// provide dependenciesdependencies: [NodeFileSystem.layer]}) {}// Layer for use in the applicationconst layer: Layer.Layer<Cache> = Cache.Default// Layer without dependencies providedconst layerNoDeps: Layer.Layer<Cache, never, FileSystem.FileSystem> =Cache.DefaultWithoutDependencies// `Cache` type also represents the service itselfdeclare const cache: Cachecache.lookup("foo")
Effect/Layer.provide accepts multiple layers
The Effect.provide
& Layer.provide
apis can now accept multiple layers to be provided.
typescript
someEffect.pipe(Effect.provide([layer1, layer2, layer3]))
typescript
someEffect.pipe(Effect.provide([layer1, layer2, layer3]))
Effect.provide now supports ManagedRuntime
You can now provide a ManagedRuntime
to an effect, allowing you to use the
services from the ManagedRuntime
inside of the effect.
typescript
import { Effect, Layer, ManagedRuntime } from "effect"const runtime = ManagedRuntime.make(Layer.empty)someEffect.pipe(Effect.provide(runtime))
typescript
import { Effect, Layer, ManagedRuntime } from "effect"const runtime = ManagedRuntime.make(Layer.empty)someEffect.pipe(Effect.provide(runtime))
Effect.mapAccum & Array.mapAccum preserve non-emptyness
If you use a NonEmptyArray
with Effect.mapAccum
or Array.mapAccum
, the
result will now be typed as a NonEmptyArray
.
Predicate.isRegExp
You can use this api to determine if a value is a RegExp
.
typescript
import { Predicate } from "effect"assert.deepStrictEqual(Predicate.isRegExp(/a/), true)assert.deepStrictEqual(Predicate.isRegExp("a"), false)
typescript
import { Predicate } from "effect"assert.deepStrictEqual(Predicate.isRegExp(/a/), true)assert.deepStrictEqual(Predicate.isRegExp("a"), false)
Tuple.map
Tuple.map
can be used to transform each element of a tuple using a function.
typescript
import { pipe, Tuple } from "effect"const result = pipe(// ^? [string, string, string]["a", 1, false] as const,Tuple.map((el) => {// ^? "a" | 1 | falsereturn el.toString().toUpperCase()}))assert.deepStrictEqual(result, ["A", "1", "FALSE"])
typescript
import { pipe, Tuple } from "effect"const result = pipe(// ^? [string, string, string]["a", 1, false] as const,Tuple.map((el) => {// ^? "a" | 1 | falsereturn el.toString().toUpperCase()}))assert.deepStrictEqual(result, ["A", "1", "FALSE"])
Array.pad
This api can be used to add elements to the end of an array until it reaches the desired length.
typescript
import { Array } from "effect"const arr = [1, 2, 3]const result = Array.pad(arr, 6, 0)assert.deepStrictEqual(result, [1, 2, 3, 0, 0, 0])
typescript
import { Array } from "effect"const arr = [1, 2, 3]const result = Array.pad(arr, 6, 0)assert.deepStrictEqual(result, [1, 2, 3, 0, 0, 0])
Other changes
There were several other smaller changes made. Take a look through the CHANGELOG to see them all: CHANGELOG.
Don't forget to join our Discord Community to follow the last updates and discuss every tiny detail!