diff --git a/html/404.html b/html/404.html new file mode 100644 index 0000000..f98b83d --- /dev/null +++ b/html/404.html @@ -0,0 +1,120 @@ + + + + + The page is not found + + + + + +

nginx error!

+ +
+ +

The page you are looking for is not found.

+ +
+

Website Administrator

+
+

Something has triggered missing webpage on your + website. This is the default 404 error page for + nginx that is distributed with + AlmaLinux. It is located + /usr/share/nginx/html/404.html

+ +

You should customize this error page for your own + site or edit the error_page directive in + the nginx configuration file + /etc/nginx/nginx.conf.

+ +

For information on AlmaLinux, please visit the AlmaLinux website.

+ +
+
+ +
+ [ Powered by nginx ] + [ Powered by AlmaLinux ] +
+
+ + \ No newline at end of file diff --git a/html/50x.html b/html/50x.html new file mode 100644 index 0000000..53e02c2 --- /dev/null +++ b/html/50x.html @@ -0,0 +1,120 @@ + + + + + The page is temporarily unavailable + + + + + +

nginx error!

+ +
+ +

The page you are looking for is temporarily unavailable. Please try again later.

+ +
+

Website Administrator

+
+

Something has triggered missing webpage on your + website. This is the default error page for + nginx that is distributed with + AlmaLinux. It is located + /usr/share/nginx/html/50x.html

+ +

You should customize this error page for your own + site or edit the error_page directive in + the nginx configuration file + /etc/nginx/nginx.conf.

+ +

For information on AlmaLinux, please visit the AlmaLinux website.

+ +
+
+ +
+ [ Powered by nginx ] + [ Powered by AlmaLinux ] +
+
+ + \ No newline at end of file diff --git a/html/OVERVIEW_GP1.html b/html/OVERVIEW_GP1.html new file mode 100644 index 0000000..8a6e89a --- /dev/null +++ b/html/OVERVIEW_GP1.html @@ -0,0 +1,550 @@ +

Overview of the GP1 Programming Language

+

Description

+

GP1 is a statically typed, multi-paradigm programming language with +an emphasis on brevity and explicitness. It provides both value and +reference types, as well as higher-order functions and first-class +support for many common programming patterns.

This document serves as a quick, informal reference for developers of GP1 (or anyone who's curious).

+

Variables and Constants

+

A given "variable" is defined with either the var or +con keyword, for mutable and immutable assignment +respectively, alonside the assignment operator, <-. An +uninitialized variable MUST have an explicit type, and cannot be +accessed until it is assigned. A variable that is initialized in its +declaration may have an explicit type, but the type may be inferred +here, when possible, if one is omitted. Normal type-coercion rules apply +in assignments, as described in the Coercion and Casting +section.

+

Non-ascii unicode characters are allowed in variable names as long as +the character doesn't cause a parsing issue. For example, whitespace +tokens are not allowed in variable names.

+

Some examples of assigning variables:

+
var x: i32;  // x is an uninitialized 32-bit signed integer
+var y <- x;  // this won't work, because x has no value
+x <- 7;
+var y <- x;  // this time it works, because x is now 7
+
+con a: f64 <- 99.8;  // a is immutable
+a <- 44.12;          // this doesn't work, because con variables cannot be reassigned
+

The following lines are equivalent,

+
con a <- f64(7.2);
+con a: f64 <- 7.2;
+con a <- 7.2;        // 7.2 is implicitly of type f64
+con a <- 7.2D;       // With an explicit type suffix
+

as are these.

+
var c: f32 <- 9;
+var c <- f32(9);
+var c: f32 <- f32(9);
+var c <- 9F;
+

Variable assignments are expressions in GP1, which can enable some +very interesting code patterns. For example, it allows multiple +assignments on one line with the following syntax. +con a <- var b <- "death and taxes" assigns the +string "death and taxes" to both a and +b, leaving you with one constant and one variable +containing separate instances of identical data. This is equivalent to +writing con a <- "death and taxes" and +var b <- "death and taxes" each on their own line. +Assignment as an expression also eliminates much of the need to define +variables immediately before the control structure in which they're +used, which improves readability.

+

Intrinsic Types

+

Numeric Types

+

u8 u16 u32 u64 +u128 u256 usize +byte

+

i8 i16 i32 i64 +i128 i256 isize

+

f16 f32 f64 f128 +f256

+

GP1 has signed integer, unsigned integer, and floating point numeric +types. Numeric types take the form of a single-letter indicator followed +by the type's size in bits. The indicators are i +(signed integer), u (unsigned integer), and +f (floating point). usize and +isize are pointer-width types. For example, on a 64-bit +system, usize is a 64-bit unsigned integer. However, it +must be cast to u64 when assigning to a u64 +variable. The type byte is an alias for u8. +Numeric operators are as one expects from C, with the addition of +** as a power operator.

+

Numeric literals have an implicit type, or the type can be specified +by a case-insensitive suffix. For example:

+
var i1 <- 1234;    // implicitly i32
+var f1 <- 1234.5;  // implicitly f64
+
+var i3 <- 1234L;   // i64
+var u3 <- 1234ui;  // u32
+var f2 <- 1234.6F; // f32
+

The complete set of suffixes is given.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
suffixcorresponding type
si16
ii32
li64
pisize
bbyte
usu16
uiu32
ulu64
upusize
ff32
df64
qf128
+

Booleans

+

bool is the standard boolean type with support for all +the usual operations. The boolean literals are true and +false. Bool operators are as one expects from C, with the +exception that NOT is !! instead of !.

+

Bitwise Operators

+

Bitwise operators can be applied only to integers and booleans. They +are single counterparts of the doubled boolean operators, e.g. boolean +negation is !!, so bitwise negation is !.

+

Strings and Characters

+

char is a unicode character of variable size. Char +literals are single-quoted, e.g. 'c'. Any single valid char +value can be used as a literal in this fasion.

+

string is a unicode string. String literals are +double-quoted, e.g. "Hello, World.".

+

Arrays

+

GP supports typical array operations.

+
var tuples : (int, int)[]; // declare array of tuples
+var strings : string[];    // declare array of strings
+
+var array <- i32[n];       // declare and allocate array of n elements
+                           // n is any number that can be coerced to usize
+
+con nums <- {1, 2, 3};     // immutable array of i32
+
+

Use the length property to access the number of elements +in an allocated array. Attempting to access length of an +unallocated array is an exception.

+

+var colors <- {"Red", "White", "Blue"};  // allocate array
+
+var count <- colors.length; // count is usize(3)
+
+

Arrays can be indexed with any integer type (signed or unsigned). +Negative values wrap from the end (-1 is the last element). An exception +occurs if the value is too big, i.e.no modulo operation is +performed.

+
var w <- {1, 2, 3, 4, 5, 6, 7};
+
+w[0]  // first element, 1
+w[-1] // last element, 7
+
+var x <- isize(-5);
+w[x]  // 5th to last element, 3
+
+

Tuples

+

Tuples group multiple values into a single value with anonymous, +ordered fields. () is an empty tuple. +("hello", i32(17)) is a tuple of type +(string i32). Tuple fields are named like indices, +i.e.(u128(4), "2").1 would be "2".

+

The unit type, represented as a 0-tuple, is written +().

+

Regex

+

regex is a regular expression. GP1 regex format is +identical to that of .NET 5 and very similar to that of gawk.

+

Named Functions

+

Some examples of defining named functions:

+
fn sum(a: f32, b: f32): f32 { a + b }        // takes parameters and returns an f32
+
+fn twice_println(s: string) {                // takes parameters and implicitly returns ()
+    println("${s}\n${s}");
+}
+
+fn join_println(a: string, b: string): () {  // takes parameters and explicitly returns ()
+    println("${a} ${b}");
+}
+
+fn seven(): u32 { 7 }                        // takes no parameters and returns the u32 value of 7
+

There are a number of syntaxes allowed for calling a given function. +This is because the caller is allowed to assign to zero or more of that +function's parameters by name. Parameters assigned by name are freely +ordered, while those assigned normally bind to the first parameter +ordered from left to right in the function definition that is +unassigned. With regard to the join_println function +defined above, this means that all of the following are valid and behave +identically.

+
join_println(a <- "Hello,", b <- "World.");
+join_println(b <- "World.", a <- "Hello,");
+join_println(b <- "World.", "Hello,");
+join_println("Hello,", "World.");
+

Function names may be overloaded. For example, +join_println could be additionally defined as

+
fn join_println(a: string, b: string, sep: string) {    
+    println("${a}${sep}${b}");
+}
+

and then both join_println("Hello,", "World.", " ") and +join_println("Hello,", "World.") would be valid calls.

+

Functions may be defined and called within other functions. You may +be familar with this pattern from functional languages like F#, wherein +a wrapper function is often used to guard an inner recursive function +(GP1 permits both single and mutual recursion in functions). For +example:

+
fn factorial(n: u256): u256 {
+    fn aux(n: u256, accumulator: u256): u256 {
+        match n > 1 {
+            true => aux(n - 1, accumulator * n),
+            _ => accumulator,
+        }
+    }
+    aux(n, 1)
+}
+

Arguments are passed by value by default. For information on the +syntax used in this example, refer to Control Flow.

+

Anonymous Functions

+

Closures

+

Closures behave as one would expect in GP1, exactly like they do in +most other programming languages that feature them. Closures look like +this:

+
var x: u32 <- 8;
+
+var foo <- { y, z => x * y * z};     // foo is a closure; its type is fn<u32 | u32>
+assert(foo(3, 11) == (8 * 3 * 11));  // true
+
+x <- 5;
+assert(foo(3) == (8 * 3 * 11));  // true
+
+con bar <- { => x * x };    // bar is a closure of type `fn<u32>`
+
+assert(bar() == 25);        // true because closure references already-defined x
+

They are surrounded by curly braces. Within the curly braces goes an +optional, comma-separated parameter list, followed by a required +=> symbol, followed by an optional expression. If no +expression is included, the closure implicitly returns +().

+

The reason the match-expression uses the same => +symbol is because the when section of a match arm is an +implicit closure. The reason => in particular was chosen +for closures is twofold. One, arrows are conventional for expressing +anonymous functions, and two, the space between the lines of an equals +sign is enclosed by them.

+

Lambdas

+

Lambdas are nearly identical to closures, but they don't close over +their environment, and they use the -> symbol in place +of =>. A few examples of lambdas:

+
con x: u32 <- 4;  // this line is totally irrelevant
+
+con square <- { x -> x * x };                 // this in not valid, because the type of the function is not known
+con square <- { x: u32 -> x * x };            // this if fine, because the type is specified in the lambda
+con square: fn<u32 | u32> <- { x -> x * x };  // also fine, because the type is specified in the declaration
+

Function Types

+

Functions are first-class citizens in GP1, so you can assign them to +variables, pass them as arguments, &c.However, using the function +definition syntax is suboptimal when using function types. Instead, +there is a separate syntax for function types. Given the function +fn sum(a: f64, b: f64): f64 { a + b } the function type is +expressed fn<f64 f64 | f64>, meaning a function that +accepts two f64 values and returns an f64. Therefore,

+
fn sum(a: f64, b: f64): f64 { a + b } 
+
con sum: fn<f64 f64 | f64> <- { a, b -> a + b };
+
con sum <- { a: f64, b: f64 -> a + b };
+

are all equivalent ways of binding a function of type +fn<f64 f64 | f64> to the constant sum. +Here's an example of how to express a function type for a function +argument.

+
fn apply_op(a: i32, b: i32, op: fn<i32 i32 | i32>): i32 {
+    op(a, b)
+}
+

Function Type Inference

+

The above example provides an explicit type for the argument +op. You could safely rewrite this as

+
fn apply_op(a: i32, b: i32, op: fn): i32 {
+    op(a, b)
+}
+

because the compiler can safely infer the function type of +op. Type inference only works to figure out the function +signature, so fn apply_op(a:i32, b:i32, op):i32 { . . . } +is not allowed.

+

Coercion and Casting

+

Refer to Variables and Constants for information on the +syntax used in this section.

+

Numeric types are automatically coerced into other numeric types as +long as that coercion is not lossy. For example,

+
var x: i32 <- 10;
+var y: i64 <- x;
+

is perfectly legal (the 32-bit value fits nicely in the 64-bit +variable). However, automatic coercion doesn't work if it would be +lossy, so

+
var x: i64 <- 10;
+var y: i32 <- x;
+

doesn't work. This holds for numeric literals as well. +Unsurprisingly, var x: i32 <- 3.14 wouldn't compile. The +floating point value can't be automatically coerced to an integer type. +So what does work? Casting via the target type's pseudo-constructor +works.

+
con x: f64 <- 1234.5;        // okay because the literal can represent any floating point type
+con y: f64 <- f16(1234.5);   // also okay, because any f16 can be losslessly coerced to an f64
+con z: i32 <- i32(x);        // also okay; uses the i32 pseudo-constructor to 'cast' x to a 32-bit integer
+
+assert(z == 1234)
+
+con a: f64 <- 4 * 10 ** 38;  // this value is greater than the greatest f32
+con b: f32 <- f32(a);        // the value of b is the maximum value of f32
+

This approach is valid for all intrinsic types. For example, +var flag: bool <- bool(0) sets flag to +false and var txt: string <- string(83.2) +sets txt to the string value "83.2". Such +behavior can be implemented by a programmer on their own types via a +system we'll discuss in the Interfaces section.

+

Program Structure

+

Every GP1 program has an entry-point function. Within that function, +statements are executed from top to bottom and left to right. The +entry-point function can be declared with the entry keyword +in place of fn and returns an integer, which will be +provided to the host operating system as an exit code. Naturally, this +means that the handling of that code is platform-dependent once it +passes the program boundry, so it's important to keep in mind that a +system may implicitly downcast or otherwise modify it before it is made +available to the user. If no exit code is specified, or if the return +type of the function is not an integer, GP1 assumes an exit code of +usize(0) and returns that to the operating system.

+

The following program prints Hello, World. and exits with an error +code.

+
entry main(): usize {
+    hello_world();
+    1
+}
+
+fn hello_world() {
+    println("Hello, World.");
+}
+

The entry function may have any name; it's the entry +keyword that makes it the entry point. The entry function may also be +implicit. If one is not defined explicitly, the entire file is treated +as being inside an entry function. Therefore,

+
println("Hello, World.");
+

is a valid and complete program identical to

+
entry main(): usize {
+    println("Hello, World.");
+}
+

This behavior can lend GP1 a very flexible feeling akin to many +scripting languages.

+

In a program where there is an entry-point specified, only +expressions made within that function will be evaluated. This means that +the following program does NOT print anything to the console.

+
entry main(): usize {
+    con x: usize <- 7;
+}
+
+println("This text will not be printed.");
+

In fact, this program is invalid. Whenever there is an explicit entry +point, no statements may be made in the global scope.

+

Control Flow

+

Conditionals

+

At this time, GP1 has only one non-looping conditional control +structure, in two variants: match and +match all. The syntax is as follows, where +*expr* are expressions and pattern* are +pattern matching options (refer to Pattern Matching for more +info).

+
match expr {
+    pattern1 => arm_expr1,
+    pattern2 => arm_expr2,
+    _ => arm_expr3,
+}
+

The match expression executes the first arm that matches +the pattern passed in expr. The match all +expression executes all arms that match the pattern. Both flavors return +their last executed expression.

+

The when keyword may be used in a given match arm to +further restrict the conditions of execution, e.g.

+
con fs <- 43;
+
+con is_even <- match fs {
+    n when n % 2 == 0 => " is "
+    _ => " is not "
+};
+
+print(fs + is_even + "even.")
+

Loops

+

Several looping structures are supported in GP1

+ +

along with continue and break to help +control program flow. All of these are statements.

+
loop { . . . }  // an unconditional loop -- runs forever or until broken
+
for i in some_iterable { . . . }  // loop over anything that is iterable
+
while some_bool { . . . }  // classic conditional loop that executes until the predicate is false
+
do { . . .
+} while some_bool  // traditional do/while loop that ensures body executes at least once
+

Pattern Matching

+

Pattern matching behaves essentially as it does in SML, with support +for various sorts of destructuring. It works in normal assignment and in +match arms. It will eventually work in function parameter +assignment, but perhaps not at first.

+

For now, some examples.

+
a <- ("hello", "world");  // a is a tuple of strings
+(b, c) <- a;
+
+assert(b == "hello" && c == "world")
+
+fn u32_list_to_string(l: List<u32>): string {  // this is assuming that square brackets are used for linked lists
+    con elements <- match l {
+        [] => "",
+        [e] => string(e),
+        h::t => string(h) + ", " + u32_list_to_string(t),  // the bit before the arrow in each arm is a pattern
+    }                                                      // h::t matches the head and tail of the list to h and t, respectively
+    "[" + elements + "]"                                   // [s] matches any single-element list
+}                                                          // [] matches any empty list
+

Interfaces

+

Interfaces are in Version 2 on the roadmap.

+

User-Defined Types

+

Enums

+

Enums are pretty powerful in GP1. They can be the typical enumerated +type you'd expect, like

+
enum Coin { penny, nickle, dime, quarter }  // 'vanilla' enum
+
+var a <- Coin.nickle
+assert a == Coin.nickle
+
+

Or an enum can have an implicit field named value

+
enum Coin: u16 { penny(1), nickle(5), dime(10), quarter(25) }
+
+var a <- Coin.nickle;
+assert(a == Coin.nickle);
+assert(a.value == 5);
+

Or an enum can be complex with a user-defined set of fields, like

+
enum CarModel(make: string, mass: f32, wheelbase: f32) {  // enum with multiple fields
+   gt          ( "ford",  1581, 2.71018 ),
+   c8_corvette ( "chevy", 1527, 2.72288 )
+}
+

A field can also have a function type. For example

+
enum CarModel(make: string, mass: f32, wheelbase: f32, gasUsage: fn<f32 | f32>) {
+   gt          ( "ford",  1581, 2.71018, { miles_traveled -> miles_traveled / 14 } ),
+   c8_corvette ( "chevy", 1527, 2.72288, { miles_traveled -> miles_traveled / 19 } )
+}
+
+var my_car <- CarModel.c8_corvette;
+var gas_used <- my_car.gasUsage(200);  // estimate how much gas I'd use on a 200 mile trip
+

Equivalence of enums is not influenced by case values, e.g.

+
enum OneOrAnother: u16 { one(0), another(0) }
+
+con a <- OneOrAnother.one;
+con b <- OneOrAnother.another;
+
+assert(a != b);
+assert(a.value == b.value);
+

It's important to remember that enums are 100% always totally in +every concieveable fashion immutable. To make this easier to enforce, +only value types are allowed for enum fields.

+

Records

+

Records are record types, defined with the record +keyword. Fields are defined in the record block and +behavior is defined in the optional impl block.

+

For example,

+
record Something {
+    label: i32    // field label followed by some type
+} impl { . . . }  // associated functions. This is different than having functions in the fields section because impl functions are not assignable.
+

If the record implements some interface, SomeInterface, +the impl would be replaced with +impl SomeInterface, and the functions of +SomeInterface would be defined alongside any other +functions of the Something record.

+

Unions

+

Unions are the classic discriminated sum type.

+
union BinaryTree {
+    Empty,
+    Leaf: i32,
+    Node: (BinaryTree BinaryTree),
+}
+

Type Aliases

+

Refer to Generics for info on the syntax used in this +section.

+

Type aliasing is provided with the type keyword, +e.g.

+
type TokenStream Sequence<Token>
+type Ast Tree<AbstractNode>
+
+fn parse(ts: TokenStream): Ast { . . . }
+

Notice how much cleaner the function definition looks with the +aliased types. This keyword is useful mainly for readability and domain +modeling.

+

Generics

+

Generics are in Version 2 on the official GP1 roadmap. They roughly +use C++ template syntax or Rust generic syntax.

+

References and Reference +Types

+

GP1 has three operators involved in handling references, +#, &, and @. These are +immutable reference, mutable reference, and dereference, respectively. +Some examples of referencing/dereferencing values:

+
var a <- "core dumped";
+var b <- &a;                                       // b is a mutable reference to a
+                                                 
+assert(a == @b);                                  
+assert(a != b);                                   
+
+@b <- "missing ; at line 69, column 420";
+assert(a == "missing ; at line 69, column 420");
+
+b <- &"missing ; at line 420, column 69";
+assert(a != "missing ; at line 420, column 69");
+
+var c <- #b;                                       // c is an immutable reference to b
+assert(@c == b);
+assert(@@c == a);
+
+@c <- &"kablooey";                                 // this does not work. `c` is an immutable reference and cannot be used to assign its referent.
+

Naturally, only var values can be mutated through +references.

+

The reference operators may be prepended to any type, T, to describe +the type of a reference to a value of type T, e.g.

+
fn set_through(ref: &string) {  // this function takes a mutable reference to a string and returns `()`
+    @ref <- "goodbye";
+}
+
+var a <- "hello";
+set_through(&a);
+
+assert(a == "goodbye");
diff --git a/html/cats.ml b/html/cats.ml new file mode 100644 index 0000000..adcf0d0 --- /dev/null +++ b/html/cats.ml @@ -0,0 +1,70 @@ +module type Functor = sig + type 'a t + val map : ('a -> 'b) -> 'a t -> 'b t +end + +module type Applicative = sig + type 'a t + val pure : 'a -> 'a t + val apply : ('a -> 'b) t -> 'a t -> 'b t +end + +module type Monad = sig + type 'a t + val return : 'a -> 'a t + val bind : ('a -> 'b t) -> 'a t -> 'b t +end + +module ApplicativeOfMonad (M : Monad) : Applicative with type 'a t = 'a M.t = struct + type 'a t = 'a M.t + let pure = M.return + let apply f x = M.(bind (fun y -> bind (fun g -> return (g y)) f) x) +end + +module FunctorOfApplicative (A : Applicative) : Functor with type 'a t = 'a A.t = struct + type 'a t = 'a A.t + let map f x = A.(apply (pure f) x) +end + +module FunctorOfMonad (M : Monad) : Functor with type 'a t = 'a M.t = struct + include FunctorOfApplicative(ApplicativeOfMonad(M)) +end + +module MonadDerive (M : Monad) = struct + include M + include ApplicativeOfMonad(M) + include FunctorOfMonad(M) + let (>>=) x f = bind f x + let (<$>) x f = map x f + let (<*>) x f = apply x f +end + +module ListMonad = struct + type 'a t = 'a list + let return x = [x] + let rec bind (f : 'a -> 'b list) : 'a list -> 'b list = function + | [] -> [] + | x :: xs -> f x @ bind f xs +end + +module Dlm = MonadDerive(ListMonad) + +let pair x y = x, y +let cart_prod xs ys = Dlm.(pair <$> xs <*> ys) + +let () = cart_prod [1;2;3;4] ["7"; "hello there"; "forthwith!"] + |> List.iter (fun (x, y) -> print_endline @@ "(" ^ string_of_int x ^ ", " ^ y ^ ")") + + + +(* ============================================================================================= *) + +module StateMonad (S : sig type t end) = struct + type 'a t = S.t -> S.t * 'a + let return x s = (s, x) + let bind f x s = let s', a = x s in f a s' +end + +module IntStateMonad = StateMonad(struct type t = int end) + + diff --git a/html/cats.ml.txt b/html/cats.ml.txt new file mode 100644 index 0000000..adcf0d0 --- /dev/null +++ b/html/cats.ml.txt @@ -0,0 +1,70 @@ +module type Functor = sig + type 'a t + val map : ('a -> 'b) -> 'a t -> 'b t +end + +module type Applicative = sig + type 'a t + val pure : 'a -> 'a t + val apply : ('a -> 'b) t -> 'a t -> 'b t +end + +module type Monad = sig + type 'a t + val return : 'a -> 'a t + val bind : ('a -> 'b t) -> 'a t -> 'b t +end + +module ApplicativeOfMonad (M : Monad) : Applicative with type 'a t = 'a M.t = struct + type 'a t = 'a M.t + let pure = M.return + let apply f x = M.(bind (fun y -> bind (fun g -> return (g y)) f) x) +end + +module FunctorOfApplicative (A : Applicative) : Functor with type 'a t = 'a A.t = struct + type 'a t = 'a A.t + let map f x = A.(apply (pure f) x) +end + +module FunctorOfMonad (M : Monad) : Functor with type 'a t = 'a M.t = struct + include FunctorOfApplicative(ApplicativeOfMonad(M)) +end + +module MonadDerive (M : Monad) = struct + include M + include ApplicativeOfMonad(M) + include FunctorOfMonad(M) + let (>>=) x f = bind f x + let (<$>) x f = map x f + let (<*>) x f = apply x f +end + +module ListMonad = struct + type 'a t = 'a list + let return x = [x] + let rec bind (f : 'a -> 'b list) : 'a list -> 'b list = function + | [] -> [] + | x :: xs -> f x @ bind f xs +end + +module Dlm = MonadDerive(ListMonad) + +let pair x y = x, y +let cart_prod xs ys = Dlm.(pair <$> xs <*> ys) + +let () = cart_prod [1;2;3;4] ["7"; "hello there"; "forthwith!"] + |> List.iter (fun (x, y) -> print_endline @@ "(" ^ string_of_int x ^ ", " ^ y ^ ")") + + + +(* ============================================================================================= *) + +module StateMonad (S : sig type t end) = struct + type 'a t = S.t -> S.t * 'a + let return x s = (s, x) + let bind f x s = let s', a = x s in f a s' +end + +module IntStateMonad = StateMonad(struct type t = int end) + + diff --git a/html/culture.dot.png b/html/culture.dot.png new file mode 100644 index 0000000..15967af Binary files /dev/null and b/html/culture.dot.png differ diff --git a/html/culture.dot.svg b/html/culture.dot.svg new file mode 100644 index 0000000..efe3216 --- /dev/null +++ b/html/culture.dot.svg @@ -0,0 +1,114 @@ + + + + + + + + + +cp + +Consider Phlebas + + + +ltw + +Look to Windward + + + +cp->ltw + + + + + +pog + +The Player of Games + + + +uow + +Use of Weapons + + + +sota + +The State of the Art + + + +uow->sota + + + + + +ivs + +Inversions + + + +uow->ivs + + + + + +sd + +Surface Detail + + + +uow->sd + + + + + +ex + +Excession + + + +mat + +Matter + + + +ex->mat + + + + + +hs + +The Hydrogen Sonata + + + +ex->hs + + + + + +ltw->sd + + + + + diff --git a/html/culture.dot.txt b/html/culture.dot.txt new file mode 100644 index 0000000..62638db --- /dev/null +++ b/html/culture.dot.txt @@ -0,0 +1,21 @@ +digraph { + node [style=filled, fontname="Open Sans", fillcolor="#cceeddff", color="#aaaaaaff"]; + ratio=0.5; + cp [label=<Consider Phlebas>]; + pog [label=<The Player of Games>]; + uow [label=<Use of Weapons>]; + sota [label=<The State of the Art>]; + ex [label=<Excession>]; + ivs [label=<Inversions>]; + ltw [label=<Look to Windward>]; + mat [label=<Matter>]; + sd [label=<Surface Detail>]; + hs [label=<The Hydrogen Sonata>]; + cp -> ltw; // It's about the Idiran War, dummy. + uow -> sota; // It's largely about Sma. + uow -> ivs; // This book gives the best idea about what SC is, and you should know that before reading Inversions. + ex -> hs; // Hydrogen Sonata is dual to Excession in many ways. Not a hard rule, but HS is better if you know Excession. + ex -> mat; // Sleeper Service mentioned as "The granddaddy, the exemplary hero figure, the very God...". + uow -> sd; // Zakalwe/chair killer is in this one, and you should know who that is. + ltw -> sd; // LTW is more impactful (with Chel heaven being specially real) without the knowledge of SD. +} diff --git a/html/index_master.html b/html/index_master.html new file mode 100644 index 0000000..fbd4792 --- /dev/null +++ b/html/index_master.html @@ -0,0 +1,19 @@ +

Page script failed to run. Please enable javascript.

+ + + diff --git a/html/msvcr110.dll b/html/msvcr110.dll new file mode 100644 index 0000000..dd484a5 Binary files /dev/null and b/html/msvcr110.dll differ diff --git a/html/nginx-logo.png b/html/nginx-logo.png new file mode 100644 index 0000000..638b499 Binary files /dev/null and b/html/nginx-logo.png differ diff --git a/html/recipes/AmarettiCookies.pdf b/html/recipes/AmarettiCookies.pdf new file mode 100644 index 0000000..15b3c4d Binary files /dev/null and b/html/recipes/AmarettiCookies.pdf differ diff --git a/html/recipes/CoronationChicken.pdf b/html/recipes/CoronationChicken.pdf new file mode 100644 index 0000000..b97f100 Binary files /dev/null and b/html/recipes/CoronationChicken.pdf differ diff --git a/html/recipes/EasySalsa.pdf b/html/recipes/EasySalsa.pdf new file mode 100644 index 0000000..060b56d Binary files /dev/null and b/html/recipes/EasySalsa.pdf differ diff --git a/html/recipes/index.html b/html/recipes/index.html new file mode 100644 index 0000000..d5f3cf7 --- /dev/null +++ b/html/recipes/index.html @@ -0,0 +1,6 @@ +
    +
  1. Coronation Chicken
  2. +
  3. Easy Medium Salsa
  4. +
  5. Amaretti Cookies
  6. +
+ diff --git a/html/resumE.pdf b/html/resumE.pdf new file mode 100644 index 0000000..8da026e Binary files /dev/null and b/html/resumE.pdf differ diff --git a/html/styles.css b/html/styles.css new file mode 100644 index 0000000..361b41f --- /dev/null +++ b/html/styles.css @@ -0,0 +1,9 @@ +body { + background-color: powderblue; +} +h1 { + color: blue; +} +p { + color: red; +} diff --git a/html/yth-name.html b/html/yth-name.html new file mode 100644 index 0000000..58fc8ff --- /dev/null +++ b/html/yth-name.html @@ -0,0 +1,3 @@ +

"Ytheleus" is the second part of a name, "Sisela Ytheleus 1/2", belonging to a spirited type D-4 military drone of the explorer ship "Peace Makes Plenty", a vessel of the Stargazer Clan, part of the Fifth Fleet of the Zetetic Elench - from Iain M. Banks' fifth Culture novel, Excession.

+ +

"One should always be prepared for every eventuality, even if it's getting shafted by a dope with bigger guns."