diff --git a/packages/effect-lens-next/src/View.ts b/packages/effect-lens-next/src/View.ts
index 27cd1d8..bc0160d 100644
--- a/packages/effect-lens-next/src/View.ts
+++ b/packages/effect-lens-next/src/View.ts
@@ -99,6 +99,30 @@ export const mapOptionEffect: {
onNone: () => Effect.succeed(Option.none()),
})))
+/** Converts typed failures from both channels into `Result` values. */
+export const result = (
+ self: View,
+): View, never, R> => make({
+ get get() { return Effect.result(self.get) },
+ get changes() { return Stream.result(self.changes) },
+})
+
+/**
+ * Combines the current values and streams of changes from multiple `View` values.
+ */
+export const zipLatestAll = []>(
+ ...elements: T
+): View<
+ [T[number]] extends [never]
+ ? never
+ : { [K in keyof T]: T[K] extends View ? A : never },
+ [T[number]] extends [never] ? never : T[number] extends View ? E : never,
+ [T[number]] extends [never] ? never : T[number] extends View ? R : never
+> => make({
+ get: Effect.all(elements.map(view => view.get)),
+ changes: Stream.zipLatestAll(...elements.map(view => view.changes)),
+}) as any
+
/** Maps errors from both the current value and the stream of changes. */
export const mapError: {
@@ -192,14 +216,6 @@ export const retry: {
get changes() { return Stream.retry(self.changes, policy) },
}))
-/** Converts typed failures from both channels into `Result` values. */
-export const result = (
- self: View,
-): View, never, R> => make({
- get get() { return Effect.result(self.get) },
- get changes() { return Stream.result(self.changes) },
-})
-
/** Narrows the focus to a field of an object. */
export const focusObjectOn: {
diff --git a/packages/effect-lens/src/Subscribable.ts b/packages/effect-lens/src/Subscribable.ts
index c2ac183..9e6d107 100644
--- a/packages/effect-lens/src/Subscribable.ts
+++ b/packages/effect-lens/src/Subscribable.ts
@@ -40,6 +40,22 @@ export const mapOptionEffect: {
onNone: () => Effect.succeed(Option.none()),
})))
+/**
+ * Combines the current values and streams of changes from multiple `Subscribable` values.
+ */
+export const zipLatestAll = []>(
+ ...elements: T
+): Subscribable.Subscribable<
+ [T[number]] extends [never]
+ ? never
+ : { [K in keyof T]: T[K] extends Subscribable.Subscribable ? A : never },
+ [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? E : never,
+ [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? R : never
+> => Subscribable.make({
+ get: Effect.all(elements.map(view => view.get)),
+ changes: Stream.zipLatestAll(...elements.map(view => view.changes)),
+}) as any
+
/**
* Maps errors from both the current value and the stream of changes.