Core Library

fble-0.5 (2025-07-13,fble-0.4-212-ga8f8ad0f)

This tutorial goes over some of the types and functions available from the core library.

You've learned about all the fble language features already. The core library is implemented on top of those language features as a common set of types and functions useful in programming with fble. Making use of the core library saves you the effort of defining and implementing these types yourself.

The core library is not part of the language specification. Thus far it has grown organically based on the needs of the sample applications included with the fble release.

The following sections highlight various useful parts of the core library.

/Core/Unit%

The /Core/Unit% module defines type Unit@ and value Unit that we have seen many times in this series of tutorials:

@ Unit@ = *();

Unit@ Unit = Unit@();

By itself Unit@ is not very interesting, but it's a building block used in all other data types.

/Core/Bool%

The /Core/Bool% module defines a boolean type Bool@, values True and False, and a few functions that operate on booleans, such as And, Or, and Not:

@ Bool@ = +(Unit@ true, Unit@ false);

Bool@ True = Bool@(true: Unit);
Bool@ False = Bool@(false: Unit);

(Bool@) { Bool@; } Not = ...;
(Bool@, Bool@) { Bool@; } And = ...;
(Bool@, Bool@) { Bool@; } Or = ...;

/Core/Eq%

The /Core/Eq% module defines an Eq@ interface for types that can be compared for equality or other kinds of relationships.

<@>@ Eq@ = <@ T@>(T@, T@) { /Core/Bool%.Bool@; };

/Core/Maybe%

The /Core/Maybe% module defines a Maybe@ type for representing optional values. It defines functions Just and Nothing for constructing these optional values.

<@>@ Maybe@ = <@ T@> { +(T@ just, Unit@ nothing); };

<@ T@>(T@){ Maybe@<T@>; } Just = <@ T@>(T@ x) { Maybe@(just: x); };
Maybe@ Nothing = <@ T@> { Maybe@<T@>(nothing: Unit); };

/Core/Char%

The /Core/Char% module defines a Char@ type representing characters. The Char@ type is implemented as a union type with a separate field of type Unit@ for each different character which is suitable for use as a letter type in a literal expression.

Characters include digits, upper and lower case letters, punctuation, and some whitespace characters.

The /Core/Char% module defines a struct Chars that holds all the different characters. For example, you could refer to the letter A using /Core/Char%.Chars.A. It provides some more convenient names Chars.tab and Chars.nl for tab and newline characters, which are otherwise slightly awkward to refer to in fble.

There is also a /Core/Char/Show% module that defines a Show function to convert a character to a string.

/Core/Int%

The /Core/Int% module defines an Int@ type, representing unbounded integers. It's implemented on top of an IntP@ type representing positive integers.

Positive integers are described using a recursive union data type:

@ IntP@ = +(
  Unit@ 1, 
  IntP@ 2p0,
  IntP@ 2p1
);

The Int@ type is a union with positive, zero, and negative fields:

@ Int@ = +(
  IntP@ n,   # Negative integers
  Unit@ 0,
  IntP@ p    # Positive integers
);

The /Core/Int% module provides standard integer arithmetic operations: Inc, Dec, Add, Sub, Neg, Mul, Exp2, Abs. Other operations are defined in submodules:

/Core/Int/Eq%

Defines comparison operations IsZero, Eq, Lt, Le, Gt, Ge, Max, and Min.

/Core/Int/Lit%

Defines an Int function that can be used for non-negative integer literals.

/Core/Int/Div%
Defines a Div operation for integers.
/Core/Int/Sqrt%
Defines a Sqrt operation for integers.
/Core/Int/Show%
Defines a Show function for integers.

/Core/List%

The /Core/List% module defines a polymorphic list type like the one we have already seen in this tutorial series:

<@>@ List@ = <@ T@> { +(*(T@ head, List@<T@> tail) cons, Unit@ nil); };

It defines a number of functions for working with lists:

List
For constructing lists using list expressions.
Cons
For adding a value to the front of a list.
Nil
For the empty list.
Append
For appending a list to another list.
Last
For getting the last element of a list.
Init
For getting all but the last element of a list.
Concat
For flattening a list of lists into a single list.
Map
For applying a function to each element of a list.
ForEach
For iterating over elements of a list.
Reverse
For reversing the elements of a list.

There is a /Core/List/Show% module that defines a Show function for lists. It takes a function for showing an element of a list, and returns a function for showing a given list.

/Core/String%

The /Core/String% module defines the type String@ as list of characters:

@ String@ = List@<Char@>;

It defines a Str function that you can use for string literals:

# Example Use:
#   String@ s = Str|'hello, world'
(List@<Char@>) { String@; } Str = List<Char@>;

And a helper function Strs for concatenating a bunch of strings together:

(List@<String@>) { String@; } Strs = /Core/List%.Concat<Char@>;

/Core/Show%

The /Core/Show% module defines a Show@ interface for types that can be converted to strings.

<@>@ Show@ = <@ T@>(T@) { /Core/String%.String@; };

/Core/Ord%

The /Core/Ord% module defines an Ordering@ type and Ord@ interface for types that can be compared.

@ Ordering@ = +(Unit@ lt, Unit@ eq, Unit@ gt);

Ordering@ Lt = Ordering@(lt: Unit);
Ordering@ Eq = Ordering@(eq: Unit);
Ordering@ Gt = Ordering@(gt: Unit);

<@>@ Ord@ = <@ T@>(T@, T@) { Ordering@; };

/Core/Map%

The /Core/Map% module defines a map interface type Map@ parameterized by map type M@ and key type K@. Instances of the Map@ interface are available for a variety of different key types. This gives a way to map from keys to values.

There is a generic self balancing tree map implementation in /Core/Map/Tree% which works with any key type that implements the Ord@ interface.

The Map@ interface provides functions for inserting, looking up, and removing values from the map.

<<@>@,@>@ Map@ = <<@>@ M@, @ K@> {
 <@ V@> { M@<V@>; } Empty;
 <@ V@>(M@<V@>) { Bool@; } IsEmpty;
 <@ V@>(M@<V@>, K@) { Maybe@<V@>; } Lookup;
 <@ V@>(M@<V@>, K@, V@) { M@<V@>; } Insert;
 <@ V@>(M@<V@>, K@) { M@<V@>; } Delete;
 <@ V@>(M@<V@>)<@ B@>(B@, (K@, V@, B@) { B@; }) { B@; } ForEach;
 @(Empty, IsEmpty, Lookup, Insert, Delete, ForEach);
};

/Core/Set%

The /Core/Set% module defines a Set@ type for describing a set of values. It provides a wrapper around instances of the Map@ interface.

<<@>@, @>% Set = <<@>@ M@, @ K@>(Map@<M@, K@> m) {
 @ Set@ = M@<Unit@>;
 Set@ Empty;
 (Set@) { Bool@; } IsEmpty;
 (Set@, K@) { Bool@; } Contains;
 (Set@, K@) { Set@; } Insert;
 (Set@, K@) { Set@; } Delete;
 (Set@)<@ B@>(B@, (K@, B@) { B@; }) { B@; } ForEach;
 @(Set@, Empty, IsEmpty, Contains, Insert, Delete, ForEach);
};

/Core/Test%

The /Core/Test% module defines types Test@, TestSuite@ and others for writing and running unit tests.

/Core/Monad%

The /Core/Monad% module defines a monad interface like the one we saw in the Bind tutorial:

<<@>@>@ Monad@ = <<@>@ M@> {
  *(
    <@ A@>(A@) { M@<A@>; } return,
    <@ A@>(M@<A@>)<@ B@>((A@) { M@<B@>; }) { M@<B@>; } do
  );
};

/Core/Stdio%

The /Core/Stdio% module defines the Stdio@ interface for accessing standard input, output, and error streams for an arbitrary monadic type M@. It can also be used to read and write files and read environment variables.

Stream types are defined in the /Core/Stream% module. They describe an interface for reading and writing sequence of bytes represented using the Int@ type. You can interact with output streams most easily using the /Core/Stream/OStream% module, which defines PutChar, PutStr, and PutLine functions for operating on streams in terms of the Char@ type.

The /Core/Stdio% module defines the Main@ type, as a type of a main function that takes a list of arguments and returns a boolean result. The /Core/Stdio/IO% module defines a Run function for running a Main@ function with the fble-stdio program.

Next Steps

Head over to the Standard IO tutorial to learn about writing command line fble programs that can interact with their environment.