diff --git a/.changeset/spicy-tigers-dig.md b/.changeset/spicy-tigers-dig.md
new file mode 100644
index 00000000000..d67a88d9208
--- /dev/null
+++ b/.changeset/spicy-tigers-dig.md
@@ -0,0 +1,5 @@
+---
+"effect": patch
+---
+
+Improve `Predicate.all` and `Predicate.some` to support heterogeneous collections
diff --git a/packages/effect/src/Array.ts b/packages/effect/src/Array.ts
index 7898c4f4a84..1774e11a73b 100644
--- a/packages/effect/src/Array.ts
+++ b/packages/effect/src/Array.ts
@@ -12,7 +12,7 @@ import { dual, identity } from "./Function.js"
import type { TypeLambda } from "./HKT.js"
import * as internalArray from "./internal/array.js"
import * as internalDoNotation from "./internal/doNotation.js"
-import * as moduleIterable from "./Iterable.js"
+import * as Iterable_ from "./Iterable.js"
import * as Option from "./Option.js"
import * as Order from "./Order.js"
import * as Predicate from "./Predicate.js"
@@ -1057,7 +1057,7 @@ export const findFirst: {
(self: Iterable, f: (a: A, i: number) => Option.Option): Option.Option
(self: Iterable, refinement: (a: A, i: number) => a is B): Option.Option
(self: Iterable, predicate: (a: A, i: number) => boolean): Option.Option
-} = moduleIterable.findFirst
+} = Iterable_.findFirst
/**
* Finds the last element in an iterable collection that satisfies the given predicate or refinement.
@@ -2441,8 +2441,7 @@ export declare namespace ReadonlyArray {
* @since 2.0.0
*/
export type Infer> = S extends ReadonlyArray ? A
- : S extends Iterable ? A
- : never
+ : Iterable_.Iterable.Infer
/**
* @since 2.0.0
diff --git a/packages/effect/src/Iterable.ts b/packages/effect/src/Iterable.ts
index ef6e742818c..5b1e74318fd 100644
--- a/packages/effect/src/Iterable.ts
+++ b/packages/effect/src/Iterable.ts
@@ -16,6 +16,29 @@ import type * as Record from "./Record.js"
import * as Tuple from "./Tuple.js"
import type { NoInfer } from "./Types.js"
+/**
+ * @since 3.8.14
+ */
+export declare namespace Iterable {
+ /**
+ * @since 3.8.14
+ */
+ export type Infer> = S extends Iterable ? A
+ : never
+
+ /**
+ * @since 3.8.14
+ */
+ export type Return> = S extends Iterable ? R
+ : never
+
+ /**
+ * @since 3.8.14
+ */
+ export type Next> = S extends Iterable ? N
+ : never
+}
+
/**
* Return a `Iterable` with element `i` initialized with `f(i)`.
*
diff --git a/packages/effect/src/Predicate.ts b/packages/effect/src/Predicate.ts
index 8dc69e08c90..b6c07679788 100644
--- a/packages/effect/src/Predicate.ts
+++ b/packages/effect/src/Predicate.ts
@@ -18,6 +18,7 @@
*/
import { dual, isFunction as isFunction_ } from "./Function.js"
import type { TypeLambda } from "./HKT.js"
+import type { Iterable as Iterable_ } from "./Iterable.js"
import type { TupleOf, TupleOfAtLeast } from "./Types.js"
/**
@@ -948,12 +949,19 @@ export const product =
*
* @category combining
* @since 2.0.0
- * @see tuple for a more powerful, variadic version.
*/
-export const all = (
- collection: Iterable>
-): Predicate> => {
- return (as) => {
+export const all: {
+ >(
+ collection: A
+ ): Refinement<
+ Array>>,
+ Array>>
+ >
+ >(collection: A): Predicate>>>
+} = >(
+ collection: A
+) => {
+ return (as: Array>>): as is Array>> => {
let collectionIndex = 0
for (const p of collection) {
if (collectionIndex >= as.length) {
@@ -1395,7 +1403,18 @@ export const every = (collection: Iterable>): Predicate => (a
* @since 2.0.0
* @see every
*/
-export const some = (collection: Iterable>): Predicate => (a) => {
+export const some: {
+ >(
+ collection: A
+ ): Refinement<
+ Refinement.In>,
+ Refinement.Out>
+ >
+ >(collection: A): Predicate>>
+} = >(
+ collection: A
+) =>
+(a: Refinement.In>): a is Refinement.Out> => {
for (const p of collection) {
if (p(a)) {
return true