Skip to content

Instantly share code, notes, and snippets.

View telekosmos's full-sized avatar
💭
👻

Guillermo C. Martínez telekosmos

💭
👻
View GitHub Profile
@telekosmos
telekosmos / functional-tree.ts
Created September 20, 2022 12:56
Tree and map
import * as O from 'fp-ts/Option'
import { pipe } from 'fp-ts/function'
// interface Tree<A> {
type Tree<A> = {
readonly left: O.Option<Tree<A>>
readonly data: A
readonly right: O.Option<Tree<A>>
}
const subt: Tree<number> = { left: O.none, data: 7, right: O.none }
You will be given a list of stock prices for a given day and your goal is to return the
maximum profit that could have been made by buying a stock at the given price and then selling the
stock later on. For example if the input is: [45, 24, 35, 31, 40, 38, 11] then your program should
return **16** because if you bought the stock at $24 and sold it at $40, a profit of $16 was made and
this is the largest profit that could be made. If no profit could have been made, return -1.
If the given array is {100, 180, 260, 310, 40, 535, 695}, the maximum profit can earned by buying
on day 0, selling on day 3 (+210). Again buy on day 4 and sell on day 6 (+650). If the given array of prices is
sorted in decreasing order, then profit cannot be earned at all.
val jobOne: IO[Int] = IO(1+1)
val jobTwo: IO[String] = IO(List("hello", "guys").mkString(" "))
// Concurrent execution (manually)
for {
j1Fiber <- jobOne.start
j2Fiber <- jobTwo.start
i <- j1Fiber.join
s <- j2Fiber.join
} yield (i, s)
@telekosmos
telekosmos / errorhandling-dealing.md
Created April 1, 2022 09:31
Short quick description on exception handling in an effectful cats application

Error dealing and handling

(Based on this, strongly recommended for an in-depth article, tutorial on error dealing with Cats)

Business errors vs technical errors

Business/application errors should be modeled in the application and be part of a monad transformer (usually EitherT)to enrich the effect with the errors or the value depending on the result of a computation (for a longer explanation, example, see here).

But this only counts for those business or application errors (those ones you can control as they are part of the business logic), there are technical errors due to connection failures, file system issues, misconfiguration, ... Those ones are real exceptional errors which have to be dealt with. Those exception errors (actually exceptions) can be raised and recovered inside IOs and have a ubiquitous use

@telekosmos
telekosmos / eithert-for-exception.scala
Created March 15, 2022 10:15
EitherT for comprehensions
import cats._
import cats.implicits._
import cats.effect._
import cats.data.EitherT
val res: EitherT[IO, Throwable, Unit] = for {
one <- EitherT[IO, Throwable, Int](IO(1.asRight[Throwable]))
// e <- EitherT(IO((new RuntimeException).asLeft[Int]))
two <- EitherT(IO(2.asRight[Throwable]))
} yield println(one + two)
@telekosmos
telekosmos / MonadAndFs2Ops.md
Created February 18, 2022 15:31 — forked from Daenyth/MonadAndFs2Ops.md
Cheat sheet for common cats monad and fs2 operation shapes
Operation Input Result Notes
map F[A] , A => B F[B] Functor
apply F[A] , F[A => B] F[B] Applicative
(fa, fb, ...).mapN (F[A], F[B], ...) , (A, B, ...) => C F[C] Applicative
(fa, fb, ...).tupled (F[A], F[B], ...) F[(A, B, ...)] Applicative
flatMap F[A] , A => F[B] F[B] Monad
traverse F[A] , A => G[B] G[F[A]] Traversable; fa.traverse(f) == fa.map(f).sequence; "foreach with effects"
sequence F[G[A]] G[F[A]] Same as fga.traverse(identity)
attempt F[A] F[Either[E, A]] Given ApplicativeError[F, E]
@telekosmos
telekosmos / http4s.md
Created February 11, 2022 19:38
"Equations" to define and request - response as a Kleisli in http4s

http4s defines a web application as a function of requests and response, just like:

Request => Response

As we are accessing to some resource like dbs, files or even the network, there will be involved some effect in the response, so:

Request => F[Response]

Being F the (side) effect affecting the response.

@telekosmos
telekosmos / main.md
Last active February 20, 2022 10:29
Snippets on Scala type classes and implicits

FP Scala snippets

Type classes, implicits, monads, higher-kinded types.

To start with:

  • Semigroup -> combine(x: A, y: A): A associative
  • Monoid extends Semigroup -> zero: A means (combine(x, zero) == combine(zero, x) == x) (zero can be call empty, id)

And/Then:

@telekosmos
telekosmos / semigroup-on-type-classes.md
Last active May 1, 2022 14:42
Type classes + implicit values + extension methods

First, we define the type classes, which are just traits in scala:

// Type classes for Semigroup and Monoid (we will be using monoid, but this is more formal)
trait Semigroup[A] {
  def op(x: A, y: A): A // should be associative
}

trait Monoid[A] extends Semigroup[A] {
  def zero: A