Understanding the use of `unsafe-` and `safe-` functions in Effect TypeScript library internals

I've noticed in the internals for a lot of the packages (@effect/printer eg) there is a pattern of using unsafe- and safe- functions which are ultimately unwrapped using Effect.runSync. For example:

/** @internal */
export const renderStream = <A>(self: DocStream.DocStream<A>): string => Effect.runSync(renderSafe(self))

const renderSafe = <A>(self: DocStream.DocStream<A>): Effect.Effect<string> => {
// ... can throw or Effect.succeed
}

// Or

/** @internal */
export const foldMap = dual<
  <A, M>(M: monoid.Monoid<M>, f: (a: A) => M) => (self: DocTree.DocTree<A>) => M,
  <A, M>(self: DocTree.DocTree<A>, M: monoid.Monoid<M>, f: (a: A) => M) => M
>(3, (self, M, f) => Effect.runSync(foldMapSafe(self, M, f)))

const foldMapSafe = <A, M>(
  self: DocTree.DocTree<A>,
  M: monoid.Monoid<M>,
  f: (a: A) => M
): Effect.Effect<M> => {
// ... can only Effect.succeed
}


I'm wondering what the benefit of this pattern is for library internals? My understanding is that Effect.runSync is sort of the boundary layer between effect and the edge of the program, so I'm a little suprised to see if at such low levels here, but maybe I'm missing something.
Was this page helpful?