Skip to content

Instantly share code, notes, and snippets.

View docteurklein's full-sized avatar

Florian Klein docteurklein

View GitHub Profile

Magic

It’s folklore that if you’re summing a list of numbers, then you should always use strict foldl. Is that really true though? foldr is useful for lists when the function we use is lazy in its second argument. For (+) :: Int -> Int -> Int this is tyically not the case, but in some sense that’s because Int is “too strict”. An alternative representation of numbers is to represent them inductively. If we do this, sumation can be lazy, and foldr can do things that foldl simply can’t!

First, let’s define natural numbers inductively, and say how to add them:

data Nat = Zero | OnePlus Nat deriving Show

one :: Nat
@clementd-fretlink
clementd-fretlink / Environment.hs
Created March 23, 2020 16:26
Env var parsing with free applicatives
#!/usr/bin/env stack
-- stack --resolver lts-14.20 --install-ghc runghc --package either --package free
{-# LANGUAGE DeriveFunctor #-}
module Main
where
import Control.Applicative.Free
import Data.Bifunctor (first)
import Data.Either.Combinators (maybeToRight)
import Data.Either.Validation
@atacratic
atacratic / ability-tutorial.output.md
Last active April 16, 2024 12:06
Unison abilities - unofficial alternative tutorial

This tutorial explains how Unison handles 'effectful' computations, like storing state or performing I/O, using abilities. It assumes you haven't come across abilities before, and covers everything from the ground up.

This is an unofficial tutorial, written before the one on unisonweb.org/docs. The approach taken here is slow and methodical. Your first stop should be the official tutorial, if you haven't seen it already.

This doc is a Unison transcript - the source is here.

Terminology note: other languages with ability systems typically call them 'effect handlers' or 'algebraic effects', but many of the ideas are the same.

Introducing abilities

{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
-- |
-- To reproduce with curl, run mainTls (from ghci) and use
--
-- @
@ChrisPenner
ChrisPenner / Optics Cheatsheet.md
Last active April 12, 2024 14:24
Optics Cheatsheet
@chrisdone
chrisdone / DBAPI.hs
Last active April 10, 2022 07:26
Defaulting fields in a record in Haskell
{-# LANGUAGE DataKinds #-}
-- | My database API.
module DBAPI where
import Data.Defaults
data ConnSpec p = ConnSpec
{ username :: !(Required p String)
@pchiusano
pchiusano / monads.u
Last active April 21, 2024 07:40
Converting between algebraic effects and monads
-- This gist shows how we can use abilities to provide nicer syntax for any monad.
-- We can view abilities as "just" providing nicer syntax for working with the
-- free monad.
ability Monadic f where
eval : f a -> a
-- Here's a monad, encoded as a first-class value with
-- two polymorphic functions, `pure` and `bind`
type Monad f = Monad (forall a . a -> f a) (forall a b . f a -> (a -> f b) -> f b)
<?php
$num = floatval($argv[1] ?? '1e6');
echo "iterations: $num\n";
function noop() {
}
$start = microtime(true);
printf("starting raw at:\t\t%.3F s\n", $start);
@cscalfani
cscalfani / MonoidsInHaskellAnIntroductions.md
Last active November 14, 2023 09:30
Monoids in Haskell, an Introduction

Monoids in Haskell, an Introduction

Why should programmers care about Monoids? Because Monoids are a common pattern that shows up over and over in programming. And when patterns show up, we can abstract them and leverage work we've done in the past. This allows us to quickly develop solutions on top of proven, stable code.

Add Commutative Property to a Monoid (Commutative Monoid) and you have something that can be executed in parallel. With the end of Moore's Law, parallelism is our only hope to increasing processing speeds.

What follows is what I've learned after studying Monoids. It is hardly complete, but hopefully will prove to be helpful as an introduction for others.

Monoid Lineage

const puppeteer = require('puppeteer');
const { defineSupportCode } = require('cucumber')
defineSupportCode(({ Before, Given, When, Then }) => {
Before({ timeout: 60 * 1000 }, async function testCase() {
this.browser = await puppeteer.launch()
})
Given('I am on google with puppeteer', { timeout: 60 * 1000 }, async function testCase() {
this.page = await this.browser.newPage()