Effect TS: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 4: Line 4:
And its not hello world
And its not hello world
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
import { Effect, pipe, Schema } from 'effect';
import { Console, Effect, pipe, Schema } from 'effect';


const Pokemon = Schema.Struct({
const Pokemon = Schema.Struct({
Line 53: Line 53:
)
)


Effect.runPromise(program).then(console.log)
Effect.runPromise(program).then(Console.log)


</syntaxhighlight>
=Second Program=
Same bat time same bat channel but this time with generators
<syntaxhighlight lang="ts">
const getPokemonB = (id: number) =>
    Effect.gen(function* (_) {
        const res = yield* _(
            Effect.tryPromise({
                try: () => fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)
                    .then(response => response.json()),
                catch: (unknown) => new Error(`Failed to fetch Pokemon with id ${id}, Error %s ${unknown}`),
            }),
        )
        return yield* _(Schema.decodeUnknown(Pokemon)((res)))
    }
)
const programB = Effect.gen(function* (_) {
    const arr = yield* _(getRandomNumberArray)
    const pokemons = yield* _(Effect.all(arr.map(getPokemonB)))
    yield* _(Effect.log("\n" + pokemons.map( (pokemon) => `${pokemon.name} ${pokemon.weight}`).join("\n")))
    const heaviestWeight = yield* _(calculateHeaviestPokemon(pokemons))
    yield* _(Effect.log(`The heaviest Pokemon weighs: ${heaviestWeight}`))
})
Effect.runPromise(programB).then(Console.log)
</syntaxhighlight>
=Handling errors=
<syntaxhighlight lang="ts">
</syntaxhighlight>
</syntaxhighlight>

Revision as of 23:31, 23 June 2025

Introduction

Dipped my toe into this. It seems to be a combination of RxJs and Microsoft DI. Not sure why it is worthwhile using types rather than a typed language. If all you have is TS resource then it makes sense. Make change my mind.

First Program

And its not hello world

import { Console, Effect, pipe, Schema } from 'effect';

const Pokemon = Schema.Struct({
  name: Schema.String,
  weight: Schema.Number,
});

type Pokemon = Schema.Schema.Type<typeof Pokemon>;

const getPokemon = (id: number) => 
    pipe(
       Effect.tryPromise({
        try: () => fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)
            .then(response => response.json()),
        catch: (unknown) => new Error(`Failed to fetch Pokemon with id ${id}, Error %s ${unknown}`),
        }),
        Effect.flatMap((data) => Schema.decodeUnknown(Pokemon)((data))),
    )

const getRandomNumberArray = Effect.all(
    Array.from({ length: 10 }, () => 
        Effect.sync(
            () => Math.floor(Math.random() * 100) +1
        )
    )
)

 const calculateHeaviestPokemon = (pokemons: Pokemon[]) => 
    Effect.reduce(pokemons, 0, (highest, pokemon) =>
        pokemon.weight === highest 
            ? Effect.fail(new Error("Two pokemons have the same weight"))
            : Effect.succeed(pokemon.weight > highest ? pokemon.weight : highest)
    )

const program = pipe(
    getRandomNumberArray,
    Effect.flatMap((arr) =>
        Effect.all(
            arr.map((arr) => getPokemon(arr))
        )
    ),
    Effect.tap((pokemons) =>
    Effect.log("\n" + pokemons.map((pokemon) => `${pokemon.name} ${pokemon.weight}`).join("\n"))),
    Effect.flatMap((pokemon) => calculateHeaviestPokemon(pokemon)),
    Effect.flatMap((heaviestWeight) => 
        Effect.log(`The heaviest Pokemon weighs: ${heaviestWeight}`)    
    ),
)

Effect.runPromise(program).then(Console.log)

Second Program

Same bat time same bat channel but this time with generators

const getPokemonB = (id: number) => 
    Effect.gen(function* (_) {
        const res = yield* _(
            Effect.tryPromise({
                try: () => fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)
                    .then(response => response.json()),
                catch: (unknown) => new Error(`Failed to fetch Pokemon with id ${id}, Error %s ${unknown}`),
            }),
        )
        return yield* _(Schema.decodeUnknown(Pokemon)((res)))
    }
)


const programB = Effect.gen(function* (_) {
    const arr = yield* _(getRandomNumberArray)
    const pokemons = yield* _(Effect.all(arr.map(getPokemonB)))
    yield* _(Effect.log("\n" + pokemons.map( (pokemon) => `${pokemon.name} ${pokemon.weight}`).join("\n")))

    const heaviestWeight = yield* _(calculateHeaviestPokemon(pokemons))
    yield* _(Effect.log(`The heaviest Pokemon weighs: ${heaviestWeight}`))
})

Effect.runPromise(programB).then(Console.log)

Handling errors