This now lives on GitHub: https://github.com/friedbrice/runhs
| #!/bin/env bash | |
| # File: /home/bjoern/.local/bin/tuxedo-profile | |
| # Check if jq is installed | |
| if ! command -v jq &> /dev/null; then | |
| echo "Error: jq is required but not installed. Please install it first." | |
| echo "You can install it with: sudo apt install jq" | |
| exit 1 | |
| fi |
| -- ghcid -c'stack repl --resolver nightly --package time' haskell-time.hs --allow-eval | |
| ---- | |
| -- # Haskell Time Crib Sheet | |
| ---- | |
| -- Excellent sources for this small guide include: | |
| -- | |
| -- * https://two-wrongs.com/haskell-time-library-tutorial.html | |
| -- * https://williamyaoh.com/posts/2019-09-16-time-cheatsheet.html |
- Put
ci.yamlinto.github/workflows/ - Follow https://github.com/cachix/cachix-action#usage to setup Cachix and benefit from quick CI build times.
Option<T> |
non-Option (T | undefined) |
|
|---|---|---|
| accessing property | userOption.map(user => user.age) |
userNullish?.age |
| calling a method | userOption.map(user => user.fn()) |
userNullish?.fn() |
| providing fallback | ageOption.getOrElse(0) |
ageNullish ?? 0 |
| filter | ageOption.filter(checkIsOddNumber) |
`ageNull |
This gist demonstrates a trick I came up with which is defining
IsString for Q (TExp a), where a is lift-able. This allows you
to write $$("...") and have the string parsed at compile-time.
On GHC 9, you are able to write $$"..." instead.
This offers a light-weight way to enforce compile-time constraints. It's
basically OverloadedStrings with static checks. The inferred return type
I've been fiddling about with an idea lately, looking at how higher-kinded types can be represented in such a way that we can reason with them in Rust here and now, without having to wait a couple years for what would be a significant change to the language and compiler.
There have been multiple discussions on introducing higher-ranked polymorphism into Rust, using Haskell-style Higher-Kinded Types (HKTs) or Scala-looking Generalised Associated Types (GATs). The benefit of higher-ranked polymorphism is to allow higher-level, richer abstractions and pattern expression than just the rank-1 polymorphism we have today.
As an example, currently we can express this type:
| {-# LANGUAGE ScopedTypeVariables #-} | |
| {-# LANGUAGE TypeApplications #-} | |
| {-# LANGUAGE FlexibleContexts #-} | |
| {-# LANGUAGE FlexibleInstances #-} | |
| {-# LANGUAGE DeriveGeneric #-} | |
| module GenericMonoid where | |
| import Data.Monoid | |
| import Data.Maybe |
| {-# LANGUAGE ConstraintKinds #-} | |
| {-# LANGUAGE DataKinds #-} | |
| {-# LANGUAGE FlexibleInstances #-} | |
| {-# LANGUAGE FunctionalDependencies #-} | |
| {-# LANGUAGE GADTs #-} | |
| {-# LANGUAGE GeneralizedNewtypeDeriving #-} | |
| {-# LANGUAGE InstanceSigs #-} | |
| {-# LANGUAGE LambdaCase #-} | |
| {-# LANGUAGE NoImplicitPrelude #-} | |
| {-# LANGUAGE NoMonomorphismRestriction #-} |
| import org.scalacheck.cats.implicits._ | |
| import org.scalacheck.Gen | |
| import io.circe.{Decoder, Encoder} | |
| object Test extends App { | |
| case class X(i: Int) | |
| implicit val x: Encoder[X] = Wrapper[X].deriveInstance[Encoder] | |
| implicit val y: Decoder[X] = Wrapper[X].deriveInstance[Decoder].withErrorMessage("some custom error msg") | |
| val z: Gen[X] = Wrapper[X].lift(Gen.choose(0, 10)) |