Skip to content

Instantly share code, notes, and snippets.

View blouerat's full-sized avatar

Bastien Louërat blouerat

View GitHub Profile
@blouerat
blouerat / etc.scala
Created August 8, 2022 15:07
The "Etc/GMT+3" time zone ID actually refers to "-03:00", as demonstrated here
import java.time.ZoneId
import java.time.format.DateTimeFormatterBuilder
import java.time.temporal.TemporalQueries
def parseZoneId(input: String): ZoneId =
new DateTimeFormatterBuilder()
.appendZoneId
.toFormatter
.parse(input)
.query(TemporalQueries.zoneId)
@blouerat
blouerat / foldMapF.scala
Created September 3, 2015 11:04
OptionT.foldMapF
def foldMapF[F[_]: Monad, A, B](o: OptionT[F, A], f: A => B)(implicit M0: Monoid[B]): F[B] = o.fold(f, M0.zero)
trait HasInverse[A]
object HasInverse {
def apply[A]: HasInverse[A] = new HasInverse[A] {}
}
implicit def dummyHasInverse[A]: HasInverse[A] = HasInverse[A]
trait Inverse[A, B] { self =>
def value: A
def inverse: B
@blouerat
blouerat / magic_applicative_2.scala
Created April 29, 2015 11:56
Monad, Applicative & Json 2
object jsonExample {
import scala.language.higherKinds
import scalaz._, Scalaz._
type Path = String
type JValue
type JObject
implicit class RichDisjunction[A, B](disjunction: A \/ B) {
@blouerat
blouerat / magic_applicative.md
Created April 27, 2015 14:53
Monad, Applicative & Json

Say we have a morally correct json library.

It comes with types like: JValue, JObject and Path.

It also has error types extending JsonError like ParsingError, CastingError and FieldError. To make it even smarter, there's a sweet Semigroup[JsonError] to accumulate errors properly (left as an exercise).

Finally, there are a bunch of basic combinators:

def parse(in: String): ParsingError \/ JValue
def retry[F[_]: Monad, E, A](f: => EitherT[F, E, A])(n: Int): EitherT[F, List[E], A] =
Stream.fill(n)(f).traverseU(_.swap).map(_.toList).swap
@blouerat
blouerat / Hadrien
Created July 21, 2014 17:40
Mémoires d'Hadrien, Marguerite Yourcenar
« Mais c'est précisément parce que j'attends peu de chose de la condition humaine, les périodes de bonheur, les progrès partiels, les efforts de recommencement et de continuité me semblent autant de prodiges qui compensent presque l'immense masse des maux, des échecs, de l'incurie et de l'erreur. Les catastrophes et les ruines viendront ; le désordre triomphera, mais de temps en temps l'ordre aussi. La paix s'installera de nouveau entre deux périodes de guerre ; les mots de liberté, d'humanité, de justice retrouveront çà et là le sens que nous avons tenté de leur donner. »
– Marguerite Yourcenar, « Mémoires d'Hadrien »
@blouerat
blouerat / roll.hs
Created July 7, 2014 11:32
1HaskellADay: roll
import Data.Tuple
{--
Okay, shoot! Fell asleep while composing a problem; sorry for the delay!
So, this one is an easy one. We get a little Forth'y'. This is from P19
of the P99 problem-set.
--}
@blouerat
blouerat / keepEqual.hs
Created June 20, 2014 07:43
1HaskellADay: keepEqual
{-| Keep equal elements that are at the same position in both lists
Examples:
>>> keepEqual "hello" "world"
"l"
>>> keepEqual (repeat 1) [0..10]
[1]
@blouerat
blouerat / iso1.hs
Last active August 29, 2015 14:02
1HaskellADay: iso1
{-# LANGUAGE TupleSections #-}
-- Follow the type and the properties
f :: Either a a -> (Bool, a)
f = either (False,) (True,)
g :: (Bool, a) -> Either a a
g (False, a) = Left a
g (True, a) = Right a