# `Skuld.Effects.FxFasterList`
[🔗](https://github.com/mccraigmccraig/skuld/blob/main/lib/skuld/effects/fx_faster_list.ex#L1)

FxFasterList - High-performance effectful list operations.

An optimized variant of `FxList` that uses `Enum.reduce_while` for
better performance. Best for computations that don't need resumable
Yield/Suspend semantics.

## When to Use FxFasterList vs FxList

| Feature                    | FxFasterList | FxList       |
|----------------------------|--------------|--------------|
| Performance                | ~0.1 µs/op   | ~0.2 µs/op   |
| Throw (error handling)     | ✓ Works      | ✓ Works      |
| Yield (suspend/resume)     | ✗ Limited*   | ✓ Full       |
| Memory                     | Lower        | Higher       |

*FxFasterList suspends but loses list context - resume returns only the
single element's result, not the full list.

**Use FxFasterList when:**
- Performance is critical
- You only use Throw for error handling (not Yield)
- You don't need to resume suspended computations

**Use FxList when:**
- You need resumable Yield/Suspend semantics (recommended default)
- You want natural control effect propagation

## Operations

- `fx_map(enumerable, f)` - Map effectful function over enumerable
- `fx_reduce(enumerable, init, f)` - Reduce with effectful function
- `fx_each(enumerable, f)` - Execute effectful function for each element (returns :ok)
- `fx_filter(enumerable, pred)` - Filter with effectful predicate

## Example

    import Skuld.Syntax

    defcomp process_users(user_ids) do
      users <- FxFasterList.fx_map(user_ids, fn id ->
        comp do
          user <- fetch_user(id)
          count <- State.get()
          _ <- State.put(count + 1)
          user
        end
      end)
      users
    end

## Implementation

FxFasterList uses `Enum.reduce_while` to iterate, running each element's
computation to completion before moving to the next. This avoids
building continuation chains, providing ~0.1 µs/op constant cost.

Control effects (Throw, Cancelled, Suspend) are detected via ISentinel
predicates (`error?/1` and `suspend?/1`) and handled explicitly - errors
propagate correctly, but Suspend loses the iteration context.

# `fx_each`

```elixir
@spec fx_each(Enumerable.t(), (term() -&gt; Skuld.Comp.Types.computation())) ::
  Skuld.Comp.Types.computation()
```

Execute an effectful function for each element, discarding results.

Returns a computation that produces `:ok`.
Each element's computation runs to completion before the next begins.

## Example

    FxFasterList.fx_each(1..1000, fn i ->
      comp do
        n <- State.get()
        _ <- State.put(n + 1)
        :ok
      end
    end)
    # => computation returning :ok

# `fx_filter`

```elixir
@spec fx_filter(Enumerable.t(), (term() -&gt; Skuld.Comp.Types.computation())) ::
  Skuld.Comp.Types.computation()
```

Filter an enumerable with an effectful predicate.

Each element's predicate runs to completion before the next begins.

## Example

    FxFasterList.fx_filter([1, 2, 3, 4], fn x ->
      comp do
        threshold <- Reader.ask()
        x > threshold
      end
    end)
    # With threshold=2 => computation returning [3, 4]

# `fx_map`

```elixir
@spec fx_map(Enumerable.t(), (term() -&gt; Skuld.Comp.Types.computation())) ::
  Skuld.Comp.Types.computation()
```

Map an effectful function over an enumerable.

Returns a computation that produces a list of results.
Each element's computation runs to completion before the next begins,
avoiding continuation chain buildup.

## Example

    FxFasterList.fx_map([1, 2, 3], fn x ->
      comp do
        count <- State.get()
        _ <- State.put(count + 1)
        x * 2
      end
    end)
    # => computation returning [2, 4, 6]

# `fx_reduce`

```elixir
@spec fx_reduce(Enumerable.t(), term(), (term(), term() -&gt;
                                     Skuld.Comp.Types.computation())) ::
  Skuld.Comp.Types.computation()
```

Reduce an enumerable with an effectful function.

Each element's computation runs to completion before the next begins.

## Example

    FxFasterList.fx_reduce([1, 2, 3], 0, fn x, acc ->
      comp do
        _ <- Writer.tell("processing #{x}")
        acc + x
      end
    end)
    # => computation returning 6

---

*Consult [api-reference.md](api-reference.md) for complete listing*
