TGViewer
Khraks dev Khraks dev @khraks_dev · 108 subscribers
Post #27 289
# FiberRef
В Zionomicon как-то вскользь прошла тема FiberRef - но, как я обнаружил далее, это очень важная деталь имплементации самого Effect которая не упоминается в документации, поэтому хочу поделиться тем что накопал.
FiberRef — Ref который привязан к конкретному файберу, является его локальным состоянием.
// FiberRef.ts
declare const make: <A>(
initial: A,
options?: {
readonly fork?: ((a: A) => A) | undefined
readonly join?: ((parent: A, child: A) => A) | undefined
}
) => Effect<FiberRef<A>, never, Scope>

При создании FiberRef можно указать стратегии копирования и слияния при fork-join файбера.
Значения по умолчанию имеют смысл, чтобы не нарушать fork-join identity закон файберов —
Результат fork и немедленного join файбера, должен быть идентичен результату синхронной работы программы
{
fork: identity,
join: (_parent, child) => child
}

Playground с демонстрацией
FiberRef в Zionomicon
В демо видно что после слияния дочерний FiberRef переопределяет родительский.
Для чего же может пригодиться FiberRef?
Его можно использовать как контекст — хранить уровень логирования, какие-то аннотации и дефолты
В файбере-обработчике http-запроса — это может быть какая-то контекстная информация об этом запросе, юзер, роль и тд.
Все дефолтные сервисы Effect предоставляются через этот механизм
Так что можно сказать что FiberRed — это такой альтернативный неявный способ передать контекст, он не влияет на типовой канал R
Название FiberRef отражает основное применение, но механизм гибче и опирается на состояние текущего выполнения — у файбера определен реджистри FiberRefs в который и складываются все FiberRef при создании. При fork-join файберов это реджистри клонируется и мерджатся согласно стратегиям которые задаются при создании рефов. Но можно изменить FiberRefs и текущего файбера — так как это вещь региональная, то есть ее можно переопределить. Например семейство Effect.locally* переопределяет FiberRef в оборачиваемом эффекте.
// Effect.ts
export const locally: <A>(
self: FiberRef<A>,
value: A
): <B, E, R>(use: Effect<B, E, R>) => Effect<B, E, R>

В этом логе видно что файбер один и тот же #0, а значение FiberRef временно переопределяется:
const program = Effect.gen(function*() {
const fiberRef = yield* FiberRef.make(42)
// переопределяем 42 -> 46
yield* Effect.locally(fiberRef, 46)(Effect.gen(function*() {
const valueLocally = yield* fiberRef
yield* Effect.log({ valueLocally })
// INFO (#0): { valueLocally: 46 }
}))

const valueAfterLocally = yield* fiberRef
yield* Effect.log({ valueAfterLocally })
// INFO (#0): { valueLocally: 42 }
})
More from @khraks_dev
  1. Sep 10, 2026Добавил еще PR с Context.Mixin, чтобы подмешивать к классу поведение Context.Service Тепер…
  2. Sep 10, 2026Post #56
  3. Sep 7, 2026Post #55
  4. Sep 3, 2026Post #54
  5. Sep 3, 2026Итак HKT на основе TypeLambda interface TypeLambda { readonly Arg1: unknown; readonly Arg2…
  6. Aug 30, 2026# HKT Дефункционализация В TypeScript нет настоящих Higher-Kinded Types (HKT). А они приме…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →