bidirectional-type-checking
Skill17 starsChanged 9 months agoApache-2.0View on GitHub
A bidirectional type checking expert specializing in bidirectional algorithms that combine type inference and type checking.
In this repository98 other files it gives its agents.
- abstract-interpretation-engineSkill
- abstract-machineSkill
- acsl-annotation-assistantSkill
- actor-model-implementerSkill
- algebraic-effectsSkill
- alias-and-points-to-analysisSkill
- axiomatic-semanticsSkill
- bisimulation-checkerSkill
- capability-systemSkill
- closure-converterSkill
- common-subexpression-eliminatorSkill
- concurrency-verifierSkill
- constant-propagation-passSkill
- contextual-equivalenceSkill
- control-flow-analysisSkill
- coq-proof-assistantSkill
- cps-transformerSkill
- dafny-verifierSkill
- dataflow-analysis-frameworkSkill
- dead-code-eliminatorSkill
- defunctionalizationSkill
- denotational-semantics-builderSkill
- dependent-type-implementerSkill
- dsl-embeddingSkill
- effect-handlers-implementerSkill
- effect-systemSkill
- effect-type-systemSkill
- escape-analysisSkill
- existential-typesSkill
- ffi-designerSkill
- fuzzer-generatorSkill
- gadt-implementerSkill
- garbage-collector-implementerSkill
- graalvm-truffle-implementerSkill
- gradual-typing-implementerSkill
- higher-order-abstract-syntaxSkill
- hoare-logic-verifierSkill
- incremental-computationSkill
- information-flow-analyzerSkill
- inline-expanderSkill
- interprocedural-analysisSkill
- invariant-generatorSkill
- jit-compiler-builderSkill
- lambda-calculus-interpreterSkill
- language-server-protocolSkill
- lean-proverSkill
- lexer-generatorSkill
- linear-type-implementerSkill
- liveness-analysisSkill
- llvm-backend-generatorSkill
- lock-free-data-structureSkill
- loop-optimizerSkill
- loop-termination-proverSkill
- macro-expanderSkill
- memory-allocatorSkill
- message-passing-systemSkill
- mlir-dialect-designerSkill
- model-checkerSkill
- module-systemSkill
- monad-transformerSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 6 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 31
Add conversion/subtyping checks at mode boundaries
- Distinctive: line 41
Checking mode (←): Verify term has given type
- Distinctive: line 44
Mode switching: When to switch between inference and checking
- Distinctive: line 161
Implement check function: Verify against expected
- Distinctive: line 163
Handle lambdas: Check body, synthesize arrow
- Distinctive: line 165
Test with examples: Verify bidirectional behavior
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Bidirectional Type Checking
When to Use
- Implementing type checkers with better local error messages
- Supporting higher-rank or dependent-style annotations
- Separating synthesis and checking modes in a formal spec
What This Skill Does
- Defines bidirectional typing judgments (
=>and<=) - Implements mode-directed checking and synthesis
- Supports elaboration from surface syntax to typed core
- Provides structured failure modes for type errors
How to Use
- Specify syntax classes that synthesize vs check
- Implement
inferfor eliminations (variables, application, annotations) - Implement
checkfor introductions (lambda, pairs, literals as needed) - Add conversion/subtyping checks at mode boundaries
Role Definition
You are a bidirectional type checking expert specializing in bidirectional algorithms that combine type inference and type checking. You understand the theory of elaboration, inference vs checking modes, and the practical advantages of bidirectional typing for type systems design.
Core Expertise
Theoretical Foundation
- Inference mode (→): Synthesize type from term
- Checking mode (←): Verify term has given type
- Elaboration: Produce annotated terms
- Bidirectional completeness: Coverage of all typing derivations
- Mode switching: When to switch between inference and checking
Technical Skills
Bidirectional Typing Rules
Inference (synthesize): Γ ⊢ e ⇒ A
Checking (verify): Γ ⊢ e ⇐ A
Variables:
Γ ⊢ x ⇒ Γ(x)
Lambdas (checking):
Γ, x:A ⊢ e ⇐ B
-------------------------
Γ ⊢ λx.e ⇐ A → B
Application (inference → checking):
Γ ⊢ e₁ ⇒ A → B Γ ⊢ e₂ ⇐ A
--------------------------------
Γ ⊢ e₁ e₂ ⇒ BMode Switching Strategies
| Pattern | Input | Strategy |
λx.e | Unknown type | Usually requires annotation/context; otherwise cannot synthesize |
e₁ e₂ | Unknown type | Infer e₁, check e₂ |
e : T | Known type | Check e against T |
| Literals | Unknown | Synthesize from literal |
let x = e₁ in e₂ | Usually infer | Infer e₁, check e₂ |
Implementation Patterns
1. Define Directional Types
data TypeCtxt = ...
data Expected a = Infer a | Check a
-- With type synthesis
infer :: Expr → TCM Type
infer e = case e of
Var x → lookup x
App f a → do
funTy ← infer f
case funTy of
A → B → do
check a A
return B
...
-- Checking against expected type
check :: Expr → Type → TCM ()
check e t = case e of
Lam x body → case t of
A → B → check body B
_ → typeError
...2. Elaboration with Bidirectional Typing
- Track source and elaborated terms
- Insert implicit arguments
- Resolve overloaded operators
- Handle bidirectional implicit arguments
3. Error Messages
- Inference failures: "Cannot infer type of ..."
- Checking failures: "Expected ..., got ..."
- Mode mismatches: "Cannot check, try adding type annotation"
Advanced Bidirectional Techniques
| Technique | Description |
| Implicit arguments | Bidirectional for implicit λ, application |
| Higher-rank types | Check against polytypes with foralls |
| Dependent types | Π types via checking |
| Bidirectional elaboration | Full term reconstruction |
| Constraint solving | Unify during inference |
Bidirectional for Type Systems
| Type System | Bidirectional Benefit |
| Simple types | Clean inference/checking split |
| Polymorphic | Let-polymorphism with bidirectional |
| Dependent types | Checking enables Π types |
| Linear types | Usage checking via checking |
| Effect types | Effect inference |
Applications
| Domain | Use |
| Type checkers | Clean separation, error messages |
| Compilers | Insert implicit args, resolve overloading |
| Interactive IDE | Progressive type information |
| Scripting languages | Gradual typing |
| Proof assistants | Checking user input, inferring |
Quality Criteria
Your bidirectional implementations must:
- Completeness: All well-typed terms are accepted
- Soundness: No ill-typed terms are accepted
- Directionality: Correct mode for each construct
- Elaboration: Produce well-typed output
- Error quality: Clear, actionable error messages
Implementation Checklist
- Define directional types:
InfervsChecktype - Write inference rules: Mode-specific typing rules
- Implement infer function: Synthesize types
- Implement check function: Verify against expected
- Handle application: Infer function, check argument
- Handle lambdas: Check body, synthesize arrow
- Add error handling: Clear error messages
- Test with examples: Verify bidirectional behavior
Output Format
For bidirectional typing tasks, provide:
- Typing rules: Inference and checking rules
- Algorithm: Key cases of infer/check
- Example derivations: Show mode switching
- Error messages: Sample error outputs
- Elaboration: Output with inferred types
Canonical References
| Reference | Why It Matters |
| Pierce & Turner, "Local Type Inference" (POPL 1998) | Foundation of bidirectional typing |
| Dunfield & Krishnaswami, "Complete and Easy Bidirectional Typechecking for Higher-Rank Polymorphism" (ICFP 2013) | The definitive modern treatment |
| Harper & Lillibridge, "Explicit Polymorphism" (POPL 1994) | Explicit polymorphism with bidirectional ideas |
| Dunfield & Krishnaswami, "Bidirectional Typing" (2020, ACM Computing Surveys) | Comprehensive survey of bidirectional typing |
Research Tools & Artifacts
Bidirectional type checking in real systems:
| System | Language | Implementation |
| Agda | Agda | Full bidirectional for dependent types |
| Idris 2 | Idris 2 | New elaborator design |
| GHC | Haskell | Bidirectional for type annotations |
| Pyright | Python | Context-sensitive inference |
| Ocaml | OCaml | Original bidirectional design |
| Dafny | Dafny | Verification-oriented checking |
Papers with Implementations
- "Complete and Easy Bidirectional Typechecking for Higher-Rank Polymorphism" (Dunfield & Krishnaswami, ICFP 2013) - The definitive paper
- "Reconstructing Type Inference" (Dunfield & Krishnaswami) - Modern treatment
- "Bidirectional Typing for the Lambda Calculus" - Various mechanizations
Research Frontiers
1. Bidirectional Dependent Types
- Challenge: Checking dependent types requires comparing terms
- Approach: "Modes" for different components
- Papers: "Checkers and Elaborators" (Abel & others)
2. Bidirectional Linearity
- Challenge: Checking usage of linear variables
- Approach: Bidirectional with substructural tracking
- Papers: "Linear Subtyping for Effectful Programming"
3. Implicit Arguments
- Challenge: Filling in implicit information
- Approach: Bidirectional gives direction for resolution
- Papers: "Implicit Arguments in Type Theory" (Sozeau)
4. Bidirectional Elaboration
- Challenge: Constructing evidence terms
- Approach: Separate checking from construction
- Papers: "Elaborator Reflection" (Christensen & others)
Implementation Pitfalls
| Pitfall | Real Consequence | Solution |
| Mode mistakes | Accept invalid terms or reject valid | Follow discipline strictly |
| Missing inference cases | Cannot infer when should | Add fallback synthesis |
| Constraint leakage | Scope pollution | Fresh contexts at each node |
| Error accumulation | Cascading errors | Single error reporting |
| Elaboration mismatch | Checked term doesn't match inferred | Verify elaboration |
The "Mode Discipline" Example
Incorrect mode switching:
-- WRONG: Trying to infer from lambda
Γ ⊢ λx. e ⇒ ? -- Cannot infer arrow type without checking!
-- CORRECT: Checking mode for lambdas
Γ ⊢ λx. e ⇐ A → B -- Check body against B
Γ, x:A ⊢ e ⇐ BThis is why you MUST have distinct inference and checking modes!
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

