# map

Transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function.

## Signatures

```ts
export declare const map: {
    <T extends RefSubject.Any | Computed.Any | Filtered.Any, B>(f: (a: Success<T>) => B): (ref: T) => T extends Filtered.Any ? Filtered<B, Error<T>, Services<T>> : Computed<B, Error<T>, Services<T>>;
    <A, E, R, B>(ref: RefSubject<A, E, R> | Computed<A, E, R>, f: (a: A) => B): Computed<B, E, R>;
    <A, E, R, B>(filtered: Filtered<A, E, R>, f: (a: A) => B): Filtered<B, E, R>;
    <R0, E0, A, E, R, B, E2, R2>(versioned: Versioned.Versioned<R0, E0, A, E, R, A, E2, R2>, f: (a: A) => B): Computed<B, E0 | E | E2, R0 | R2 | Exclude<R, Scope.Scope>> | Filtered<B, E0 | E | E2, R0 | R2 | Exclude<R, Scope.Scope>>;
};
```

## Why

`map` creates derived state instead of copying source state into a component.
Reads and pushed updates remain connected to the original `Versioned` value,
so a projection can be tested without rendering and consumed by any renderer.

## Ownership and lifetime

The returned `Computed` or `Filtered` view does not take ownership of the
source. It follows the source lifetime and preserves its error and service
channels. The pure mapping function adds neither resources nor failures.

## Re-computation

The mapping function runs for the current value and subsequent committed
source versions. Updates still occur on the writable source; the derived view
is read-only unless a more specific bidirectional combinator is used.

## Examples

```ts
import { Effect } from "effect"
import * as RefSubject from "@typed/fx/RefSubject"

const program = Effect.gen(function* () {
  const count = yield* RefSubject.make(5)

  // Create a computed that doubles the count
  const doubled = RefSubject.map(count, (n) => n * 2)

  const value = yield* doubled
  console.log(value) // 10

  // Update source
  yield* RefSubject.set(count, 7)

  // Computed automatically updates
  const newValue = yield* doubled
  console.log(newValue) // 14
})
```
