MyNixOS website logo
Description

Type-safe DSL for healthcare claims validation and X12 processing.

A type-safe, composable DSL for healthcare claims validation with both internal (Haskell) and external (text-based) syntax. Features GADT-based rules, comprehensive validation support, and business-friendly rule definitions.

Healthcare Claims X12 Processing DSL

A Domain-Specific Language (DSL) for healthcare claims validation and X12 processing, implemented in Haskell.

Overview

This project provides a type-safe, composable DSL for defining business rules for healthcare claims validation. It features both an internal DSL (embedded in Haskell) and an external DSL (text-based syntax for business analysts).

Features

  • Type-Safe Internal DSL: Uses GADTs to ensure rule correctness at compile time
  • Business-Friendly External DSL: SQL-like syntax that non-programmers can read and write
  • Comprehensive Validation: Support for amount checks, diagnosis codes, procedure codes, place of service, and claim types
  • Composable Rules: Combine simple rules into complex validation logic using AND, OR, and NOT
  • Full Test Coverage: Comprehensive test suite using Hspec

Project Structure

claims-x12-dsl/
├── src/
│   ├── Claims/
│   │   ├── Types.hs           # Core domain types and Rule GADT
│   │   ├── Interpreter.hs     # Rule evaluation engine
│   │   ├── Rules.hs           # Example business rules
│   │   ├── Parser.hs          # External DSL parser (Parsec)
│   │   └── Parser/
│   │       └── AST.hs         # Abstract syntax tree for external DSL
│   └── Lib.hs                 # Main library exports
├── app/
│   └── Main.hs                # Example application
├── test/
│   └── Spec.hs                # Test suite
├── examples/
│   └── sample-rules.dsl       # Example external DSL rules
└── package.yaml               # Project dependencies

Getting Started

Prerequisites

You'll need Stack installed. If you don't have it:

macOS:

curl -sSL https://get.haskellstack.org/ | sh

Linux:

curl -sSL https://get.haskellstack.org/ | sh

Windows: Download the installer from haskellstack.org

Installation

  1. Clone or navigate to the project:

    cd /path/to/claims-x12-dsl
    
  2. Build the project:

    stack build
    

    This will:

    • Download and install the correct GHC version (9.6.6) if needed
    • Install all dependencies
    • Compile the library and executable
    • First build takes ~60 seconds; subsequent builds are much faster
  3. Verify the build:

    stack test
    

    You should see:

    22 examples, 0 failures
    Finished in 0.0036 seconds
    

Running the Application

Run the example application:

stack run

This validates a sample $75,000 inpatient claim and displays results:

Healthcare Claims X12 Processing DSL
====================================

Validating example claim:
Claim ID: "CLM001"
Amount: $75000.00
Type: Inpatient

Validation Results:
-------------------
Rule 1: FAIL - "Review Required: High value claim exceeds $50,000"
Rule 2: PASS
Rule 3: PASS
Rule 4: PASS
Rule 5: PASS

Running Tests

Run all tests:

stack test

Run tests with detailed output:

stack test --test-arguments="--format=progress"

Run tests with coverage:

stack test --coverage

Interactive Development

Start a REPL (GHCi):

stack ghci

Then you can interactively test the DSL:

ghci> :load src/Claims/Types.hs
ghci> :load src/Claims/Interpreter.hs
ghci> import Data.Decimal
ghci> import Data.Time
-- Create a claim and test rules interactively

Usage

Internal DSL (Haskell)

import Claims.Types
import Claims.Interpreter
import Data.Decimal (realFracToDecimal)
import Data.Time (fromGregorian)

-- Define a claim
claim = Claim
  { claimId = "CLM001"
  , patientId = "PAT12345"
  , providerId = "PRV98765"
  , serviceDate = fromGregorian 2025 1 5
  , totalAmount = realFracToDecimal 2 75000
  , diagnosisCodes = ["I21.0", "I25.10"]
  , procedureCodes = ["99223", "93000"]
  , placeOfService = "21"
  , claimType = Inpatient
  }

-- Define a rule
highValueRule :: Rule ValidationResult
highValueRule = 
  If (greaterThan 50000)
    (needsReview "High value claim exceeds $50,000")
    approve

-- Evaluate the rule
result = eval claim highValueRule

External DSL (Business Analyst Syntax)

Create a rules file (e.g., rules.dsl):

RULE HighValueReview
DESCRIPTION "Flag high-value claims for manual review"
WHEN
  claim.amount > 50000
THEN
  REQUIRE_REVIEW "Claim exceeds high-value threshold"
END

RULE EmergencyRoomValidation
DESCRIPTION "Validate ER claims have appropriate diagnoses"
WHEN
  claim.place_of_service = "23" AND
  NOT (claim.has_diagnosis "S06" OR claim.has_diagnosis "I21")
THEN
  REJECT "Emergency room claim missing emergency diagnosis"
END

Parse and use the rules:

import Claims.Parser

rulesText <- readFile "rules.dsl"
case parseRules rulesText of
  Left err -> print err
  Right parsedRules -> do
    let internalRules = map convertToInternalRule parsedRules
    let results = validateClaim claim internalRules
    print results

Built-in Business Rules

The library includes several example business rules:

  1. High Value Claims Review: Claims exceeding $50,000 require manual review
  2. Emergency Room Validation: ER claims must have emergency diagnosis codes
  3. Inpatient Admission: Inpatient claims must include admission procedure codes
  4. Complex Professional Claims: Multi-condition validation for professional claims
  5. Outpatient Surgery Minimum: Outpatient surgeries must meet minimum amounts

External DSL Syntax

Conditions

  • Amount comparisons: claim.amount > 50000, claim.amount BETWEEN 0 AND 100
  • Code checks: claim.has_diagnosis "I21", claim.has_procedure "99223"
  • Claim properties: claim.type = "Inpatient", claim.place_of_service = "23"
  • Logical operators: AND, OR, NOT

Actions

  • APPROVE: Automatically approve the claim
  • REJECT "message": Reject the claim with a reason
  • REQUIRE_REVIEW "message": Flag for manual review

Dependencies

  • base: Core Haskell library
  • text: Efficient text handling
  • time: Date/time support
  • Decimal: Precise decimal arithmetic for currency
  • parsec: Parser combinator library for external DSL
  • containers: Data structures
  • hspec: Testing framework
  • QuickCheck: Property-based testing

License

BSD-3-Clause

Author

Based on the Healthcare Claims X12 Processing DSL specification.

Metadata

Version

0.1.0.0

Platforms (78)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows