APIMeta

Meta

The compile-time stage: code values, type and effect reflection, attributes, and the builders derivers use.

A backtick quotation is a Code value, and $(...) splices one back in. typeOf T reflects a type as a TypeRepr, which info reads as a schema when it is visible where typeOf was written. Code, TypeRepr, and the types built from them exist only while the compiler runs, so a definition whose type mentions them is never part of a program.

Arrow

type Arrow    = NotArrow    | Arrow ArrowInfoSource

What arrow finds.

Constructors

Arrow

Arrow : ArrowInfo -> ArrowSource

The arrow’s parts.

NotArrow

NotArrow : ArrowSource

The type is not a function arrow.

ArrowInfo

type ArrowInfo =    { param : TypeRepr    , result : TypeRepr    , effects : Items Effect    , tail : Tail    }Source

A decomposed function arrow.

Fields

param

param : TypeReprSource

The argument type.

result

result : TypeReprSource

The result type, which is itself an arrow for a curried function.

effects

effects : Items EffectSource

The effects on this arrow’s row, ordered by module and name.

tail

tail : TailSource

Whether the row is closed or open.

Attached

type Attached a =    { value : a    , site : Site    }Source

An attribute value and where it was written.

Fields

value

value : aSource

The attribute’s value.

site

site : SiteSource

Its source location.

Attributes

type AttributesSource

Generic, typed metadata. The lookup primitive is specialized by the compiler.

Bound

type Bound =    { ctor : Ctor    , fields : Items BoundField    }Source

One branch of a match: a constructor and its bound fields.

Fields

ctor

ctor : CtorSource

The constructor matched.

fields

fields : Items BoundFieldSource

Its fields, bound in order.

BoundField

type BoundField =    { name : String    , index : Int    , ty : TypeRepr    , value : Code    , attributes : Attributes    }Source

One field of a constructor that match has bound.

Fields

name

name : StringSource

The field’s name, or "" for a positional field.

index

index : IntSource

Its zero-based position.

ty

ty : TypeReprSource

Its type.

value

value : CodeSource

Code naming the bound value.

attributes

attributes : AttributesSource

Its attributes.

Code

type CodeSource

A piece of Fango code at compile time, from a quotation or a builder. It keeps the scope it was written in, and is checked when it is spliced.

Ctor

type Ctor =    { name : String    , symbol : String    , index : Int    , owner : TypeRepr    , fields : Items Field    , attributes : Attributes    }Source

One constructor of a reflected type. A record’s sole constructor carries the type’s own name.

Fields

name

name : StringSource

The constructor’s name.

symbol

symbol : StringSource

Its canonical name, which identifies it in generated code.

index

index : IntSource

Its zero-based declaration position.

owner

owner : TypeReprSource

The type it constructs.

fields

fields : Items FieldSource

Its fields in order.

attributes

attributes : AttributesSource

Its own attributes; a record’s synthetic constructor has none.

Effect

type Effect =    { name : String    , moduleName : String    , repr : EffectRepr    , args : Items TypeRepr    , attributes : Attributes    }Source

One effect application on an arrow’s row. Its identity, name, and arguments are always readable. Its attributes are readable where the effect’s operations are visible: exposing (E(..)) reflects them, while exposing (E) leaves a collection whose lookups fail at compile time.

Fields

name

name : StringSource

The effect’s name.

moduleName

moduleName : StringSource

The module that declares it.

repr

repr : EffectReprSource

The reflected application.

args

args : Items TypeReprSource

Its type arguments.

attributes

attributes : AttributesSource

The attributes written before its effect.

EffectRepr

type EffectReprSource

A reflected effect application, compared with sameEffect.

Field

type Field =    { name : String    , index : Int    , ty : TypeRepr    , attributes : Attributes    }Source

One field of a reflected constructor.

Fields

name

name : StringSource

The field’s name, or "" for a union constructor’s positional field.

index

index : IntSource

Its zero-based position.

ty

ty : TypeReprSource

Its type, instantiated at the reflected type’s arguments.

attributes

attributes : AttributesSource

Its attributes.

Items

type Items a    = NoItems    | Item a (Items a)Source

Meta’s own list. Meta cannot use List, which derives its instances and so depends on the module that depends on Meta.

Constructors

NoItems

NoItems : Items aSource

The empty list.

Item

Item : a -> Items a -> Items aSource

An item in front of the rest.

Reflected

type Reflected    = Opaque    | Visible TypeInfoSource

info answers Opaque unless the type’s schema is visible where typeOf was written: exposing (T) reflects opaque and exposing (T(..)) reflects in full, exactly as those forms already govern patterns and field access. Types with constructor-local hidden state also answer Opaque; their public type arguments and nominal identity remain available.

Constructors

Opaque

Opaque : ReflectedSource

No schema is readable: the type is imported opaquely, or it is a scalar, a type variable, or a type with constructor-local hidden state.

Visible

Visible : TypeInfo -> ReflectedSource

The type’s schema.

Shape

type Shape    = Union (Items Ctor)    | Record CtorSource

How a reflected type is built.

Constructors

Union

Union : Items Ctor -> ShapeSource

A union of these constructors.

Record

Record : Ctor -> ShapeSource

A record, as its one constructor with named fields.

Site

type SiteSource

Where an attribute was written, for reporting a failure there.

Tail

type Tail    = Closed    | Open TypeReprSource

How an arrow’s row ends.

Constructors

Closed

Closed : TailSource

The row lists every effect the arrow may perform.

Open

Open : TypeRepr -> TailSource

The row continues with this row variable.

TypeInfo

type TypeInfo =    { name : String    , moduleName : String    , ty : TypeRepr    , params : Items TypeRepr    , shape : Shape    , attributes : Attributes    }Source

The schema of a reflected type.

Fields

name

name : StringSource

The type’s name.

moduleName

moduleName : StringSource

The module that declares it.

ty

ty : TypeReprSource

The reflected type itself.

params

params : Items TypeReprSource

Its type arguments.

shape

shape : ShapeSource

Its constructors or record fields.

attributes

attributes : AttributesSource

The attributes written before its type.

TypeRepr

type TypeReprSource

A reflected type. Nominal types compare by compiler identity; applications and function arrows compare structurally, including their effects.

Lift

class Lift aSource

Values that become literal code. Int, Float, String, Char, Bool, and () have it.

Methods

lift

lift : Lift a => a -> CodeSource

A literal for the value, which keeps its own type.

Instances:

Lift ()
Lift Bool
Lift Char
Lift Float
Lift Int
Lift String

args

args : TypeRepr -> Items TypeReprSource

The arguments a type application applies, in order.

arrow

arrow : TypeRepr -> ArrowSource

Decomposes a function arrow. A curried function is an arrow whose result is another arrow, each with its own row.

import Meta exposing (Arrow(..))

resultIsString =
    $(Meta.lift
        (case Meta.arrow (typeOf (Int -> String)) of
            Arrow parts -> Meta.sameType parts.result (typeOf String)
            NotArrow -> False))

resultIsString

attributes

attributes : Type a -> Attributes -> Items (Attached a)Source

The attributes in a collection whose type is exactly a, type arguments included, in source order. Collections follow reflection visibility: an opaque import hides a type’s metadata.

construct

construct : Ctor -> Items Code -> CodeSource

construct is the other direction, for a method that produces an a.

ctorsIn

ctorsIn : TypeInfo -> Items CtorSource

ctorsIn flattens the two shapes: a record is a single constructor whose fields carry names.

declaredType

declaredType : Code -> TypeReprSource

The declared type of a quoted top-level name. Its quantified type and row variables stay variables, so isVar and sameType can relate them; its schemas are visible as they are where the quote was written. Reading a declaration that is still being checked, or code that is not a reference, stops compilation.

fail

fail : String -> CodeSource

fail stops expansion and reports COMPILE-TIME FAILURE at the splice site.

failAt

failAt : Site -> String -> aSource

Stops compilation with a COMPILE-TIME FAILURE at an attribute’s site.

foldItems

foldItems : (a -> b -> a) -> a -> Items b -> aSource

Combines the items into one value, first to last.

import Meta exposing (Items(..))

Meta.foldItems { total n -> total + n } 0 (Item 1 (Item 2 NoItems)) == 3
head : TypeRepr -> TypeReprSource

The type constructor an application applies, or the type itself.

info

info : TypeRepr -> ReflectedSource

The type’s schema, when visible where typeOf was written and without constructor-local hidden types.

isReference

isReference : Code -> BoolSource

Whether the code is a quote of exactly one top-level name, such as `List.map`.

isVar

isVar : TypeRepr -> BoolSource

Whether the type is a type variable.

lambda

lambda : String -> (Code -> Code) -> CodeSource

Give a generator a reference to a local binder and wrap its result in a lambda. The caller supplies a private name; generated bodies can then keep one typed slot per reflected field without generating declarations.

lengthItems

lengthItems : Items a -> IntSource

The number of items.

localFunction

localFunction : String -> Items String -> (Code -> Items Code -> Code) -> (Code -> Code) -> CodeSource

Build a named local function, including self-recursive references, and an expression that uses it. Names must be private and parameters nonempty.

mapItems

mapItems : (a -> b) -> Items a -> Items bSource

Applies a function to every item, keeping their order.

import Meta exposing (Items(..))

Meta.lengthItems (Meta.mapItems { n -> n * 2 } (Item 1 (Item 2 NoItems))) == 2

match

match : TypeInfo -> Code -> (Bound -> Code) -> CodeSource

match builds the exhaustive case over subject’s constructors and binds every field, handing each branch’s bindings to build. Nesting two calls produces the nested case a two-argument method needs.

sameEffect

sameEffect : Effect -> Effect -> BoolSource

Whether two effect applications are the same effect with the same arguments. Names never decide it.

sameType

sameType : TypeRepr -> TypeRepr -> BoolSource

Whether two reflected types are the same type. Names never decide it.

sequence

sequence : Code -> Code -> CodeSource

Sequence a Unit expression before a result without introducing a lambda.

siteOf

siteOf : Code -> SiteSource

Where a piece of code was written, for reporting a failure there with failAt. Code the compiler built reports at the splice site instead.

typeName

typeName : TypeRepr -> StringSource

typeName is for display only. Identity is sameType.