Skip to content

Instantly share code, notes, and snippets.

@Revolucent
Revolucent / Repository.lhs
Last active September 2, 2024 14:52
Haskell Repository Pattern With Type Classes
> {-# LANGUAGE FunctionalDependencies #-}
> module UserRepository where
This is an example of adapting the Repository pattern to Haskell using type classes, with the aim of decoupling data access from its interface for the purpose of writing better unit tests. Is this the best way to achieve this goal? Well, it's one way.
It makes the assumption that your application is using the ReaderT IO pattern promoted by libraries like rio.
First, we create a typeclass that contains our data access methods:
@Revolucent
Revolucent / Validation.swift
Created June 28, 2024 02:49
An observable, composable validation architecture that works with the Pointfree Composable Architecture
import ComposableArchitecture
import SwiftUI
enum ValidationKey<Model>: Hashable {
case model
case key(PartialKeyPath<Model>)
}
@ObservableState
struct ValidationResult: Equatable {
@Revolucent
Revolucent / Parsy.hs
Last active June 26, 2024 04:05
Haskell parser combinators written from scratch as an exercise
{-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies #-}
module Parsy where
import Control.Monad.Error.Class
import Data.List (foldr1, singleton, (!!))
import GHC.Base (empty)
import RIO hiding (optional)
import RIO.Char
@Revolucent
Revolucent / DockerSSH.md
Last active February 19, 2023 16:09
Using SSH inside a Dockerfile

SSH in a Dockerfile

Prerequisites

  • You must have BuildKit enabled in Docker.
  • You must have ~/.ssh/config set up with a proper alias for the server you want to access via SSH.
  • When referencing external resources via SSH, always use a proper domain name, never an SSH alias. In other words, use something like [email protected]:foo/bar.
  • Use the latest Dockerfile syntax using # syntax=docker/dockerfile:1.x at the top.
@Revolucent
Revolucent / Json.kt
Created January 31, 2022 17:22
Some combinators which implement a DSL for querying and deserializing Json from Strings. Extend or alter to your taste.
typealias Deserializer<I, O> = (I) -> O?
typealias JsonDeserializer<I, O> = (Json) -> Deserializer<I, O>
typealias JsonElementDeserializer = JsonDeserializer<JsonElement, JsonElement>
private fun <I, O> const(deserializer: Deserializer<I, O>): JsonDeserializer<I, O> = {
deserializer
}
infix fun <A, B, C> JsonDeserializer<A, B>.j(
next: JsonDeserializer<B, C>
@Revolucent
Revolucent / KeyboardAvoidingViewController.swift
Last active June 8, 2020 16:54
Modern implementation of KeyboardAvoidingViewController
import UIKit
open class KeyboardAvoidingViewController: UIViewController {
private var observers: [NSObjectProtocol] = []
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let nc = NotificationCenter.default
@Revolucent
Revolucent / Api.hs
Last active September 21, 2019 15:08
A simple wrapper around Network.HTTP.Req to talk to an API.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TupleSections #-}
@Revolucent
Revolucent / MapDispatchToProps.js
Created January 5, 2019 20:56
mapDispatchToProps
import parse from 'obj-parse'
/*
In its simplest usage, mapStateToProps('foo', 'bar')
maps the state keys 'foo' and 'bar' to keys of the same
name in the props.
To alias, use an object literal: mapStateToProps('foo', {baz: 'bar.buzz'}).
In this case, we're mapping state that's more deeply nested to the 'baz' prop.
The parse method of obj-parse takes care of this for us.
@Revolucent
Revolucent / Family.swift
Last active October 28, 2018 07:49
Functions for recursively finding ancestor and descendants in Swift. Useful for creating extension methods.
public func descendants<Descendant>(of parent: Descendant, in attribute: KeyPath<Descendant, [Descendant]>, where: (Descendant) throws -> Bool) rethrows -> [Descendant] {
var descendants: [Descendant] = []
for child in parent[keyPath: attribute] {
if try `where`(child) {
descendants.append(child)
}
try descendants.append(contentsOf: MASCore.descendants(of: child, in: attribute, where: `where`))
}
return descendants
}
@Revolucent
Revolucent / UIView+Rx.swift
Created October 5, 2018 02:53
isFirstResponder observable with RxSwift
import RxCocoa
import RxSwift
import UIKit
extension Reactive where Base: UIView {
var isFirstResponder: Observable<Bool> {
return Observable
.merge(
methodInvoked(#selector(UIView.becomeFirstResponder)),
methodInvoked(#selector(UIView.resignFirstResponder))