Skip to content

Instantly share code, notes, and snippets.

//greater than or equal
export const gte = <A, K extends keyof A>(field: K, val: A[K]): Filter<A> =>
or(greater(field, val), equals(field, val));
//less than or equal
export const lte = <A, K extends keyof A>(field: K, val: A[K]): Filter<A> =>
or(less(field, val), equals(field, val));
//combine 1 to many filters returning true if all are true (and)
export const all = <A>(...dsl: Filter<A>[]): Filter<A> =>
export const equals = <A, K extends keyof A>(field: K, val: A[K]): Filter<A> => ({
kind: "Equals",
field,
val
});
export const greater = <A, K extends keyof A>(field: K, val: A[K]): Filter<A> => ({
kind: "Greater",
field,
val
});
const query: Filter<JobPosting> = and(
equals("manager", "Bob Slydell"),
greater("salary", 50000)
);
console.log(
interpretToSql(query)
)
// ([manager] = 'Bob Slydell' and [salary] > '50000')
{
kind: 'And',
a: { kind: 'Equals', field: 'manager', val: 'Bob Slydell' },
b: { kind: 'Greater', field: 'salary', val: 50000 }
}
type JobPosting {
manager: string;
salary: number;
}
const filter: Filter<JobPosting> =
and(
equals("manager", "Bob Slydell"),
greater("salary", 50000)
)
export type Filter<A> =
| { kind: "Equals"; field: keyof A; val: A[keyof A] }
| { kind: "Greater"; field: keyof A; val: A[keyof A] }
| { kind: "Less"; field: keyof A; val: A[keyof A] }
| { kind: "And"; a: Filter<A>; b: Filter<A> }
| { kind: "Or"; a: Filter<A>; b: Filter<A> };
type Monoid<A> = { empty: A; append: (x: A, y: A) => A };
const sum: Monoid<number> = { empty: 0, append: (x, y) => x + y };
interface OrderType {
period: "ytd" | "mtd";
orders: number;
}
const data: OrderType[] = [
{ period: "ytd", orders: 3 },
@reidev275
reidev275 / example.ts
Last active December 9, 2019 19:07
A dsl for filtering resources. Useful as a way to serialize and transfer filters
import { Filter } from "./filterDsl"
// a sample data model
interface JobPosting {
manager: string;
position: string;
}
//a filter of the data model
const query: Filter<JobPosting> = and(
module Main where
import Prelude
import Effect (Effect)
import Effect.Console (log)
data Heading = North | South | East | West
data Position = Position
{ x ∷ Int
@reidev275
reidev275 / dsl.ts
Last active November 19, 2019 21:15
Mars Rover Kata written in TypeScript with a DSL and monoids allowing the effect to be defined by the interpreter. No Higher Kinded Types required
export type Heading = "north" | "south" | "east" | "west";
export type Position = { heading: Heading; x: number; y: number };
//recursive data structure with our core commands and type
export type DslC =
| { kind: "position"; a: Position }
| { kind: "forward"; a: DslC }
| { kind: "right"; a: DslC };
export const pos = (a: Position): DslC => ({