A functional-first scripting language with static typing
Full Hindley-Milner type inference with unification and occurs check for ints, bools, strings, and functions.
Haskell-like lambdas, precedence, keywords, and multi-statement files with expression-only core.
User input with `input`, type conversions (`parseInt`, `toString`, `show`), and interactive calculator example.
435 tests with clear pass/fail indicators, property-based testing, and script evaluation for robust quality.
CLI with help, inline evaluation, file execution, --debug flag for development, and comprehensive documentation.
All expressions type-checked before evaluation with descriptive error messages.
stack build && stack test
stack exec kai -- --help
stack exec kai -- -e "print (42 + 1)"
stack exec kai -- --debug -e "42 + 1"
stack exec kai path/to/script.kai
stack exec kai examples/calculator.kai
make install
export PATH="$HOME/.local/bin:$PATH"
kai tests/arithmetic.kai
42
-3
true
false
"hi"
()
+
-
*
/
++
==
<
>
and
or
not
if condition then expr1 else expr2
\\x -> x + 1
\\f -> f 42
let x = 42 in x + 1
let _ = print "hello" in 42
letrec factorial = \\n -> if n == 0 then 1 else n * (factorial (n - 1)) in factorial 5
let add : Int -> Int -> Int = \\x : Int -> \\y : Int -> x + y
parseInt "42"
toString 100
show (42 + 3)
[1, 2, 3]
(1, "hi", true)
{a = 1, b = true}
Just 42
Left "error"
map filter foldl
length reverse take drop zip
split join trim replace strLength
head tail null fst snd
input
print "Hello"
readFile "path"
writeFile "path" "content"
args
print "A"; print "B"; 42
42 * (10 - 3)
5 > 3 and true
not false
-5 + 3
10 / 2
7 == 7
if 5 > 3 then 42 * 2 else 0
if true and false then 1 else 2
\\x -> x + 1
(\\x -> x + 1) 5
(\\x -> x * x) 4
(\\f -> f 10) (\\n -> n * 2)
let add = \\x -> \\y -> x + y in add 5 3
letrec factorial = \\n -> if n == 0 then 1 else n * (factorial (n - 1)) in factorial 5
let compose = \\f -> \\g -> \\x -> f (g x) in compose (\\x -> x * 2) (\\x -> x + 1) 10
"Hello, " ++ "World"
print ("The answer is " ++ "42")
print (if 5 > 3 then "yes" else "no")
(\\x -> print (x ++ "!")) "Hi"
let name = input in print ("Hello, " ++ name)
let numStr = input in case parseInt numStr of Just num -> toString (num * 2) | Nothing -> "Invalid number"
show (42 + 3)
let _ = print "Setup" in let _ = print "Process" in 42
print "First"; print "Second"; print "Done"
let x = 10 in let _ = print ("x is " ++ toString x) in x * 2
let add : Int -> Int -> Int = \\x : Int -> \\y : Int -> x + y
(\\x : String -> case parseInt x of Just n -> n | Nothing -> 0) "42"
[1, 2, 3] ++ [4, 5]
head([1, 2, 3])
tail([1, 2, 3])
(1, "hello", true)
fst((42, "world"))
map (\\x -> x * 2) [1, 2, 3]
// [2, 4, 6]
filter (\\x -> x > 2) [1, 2, 3, 4]
// [3, 4]
zip [1, 2, 3] ["a", "b", "c"]
// [(1, "a"), (2, "b"), (3, "c")]
split " " "hello world"
// ["hello", "world"]
join ", " ["apple", "banana"]
// "apple, banana"
trim " hello "
// "hello"
let content = readFile "input.txt" in print content
let _ = writeFile "output.txt" "Hello!" in print "Done"
let firstArg = head args in print firstArg
// Access command-line arguments
1 + true
// Type error: TypeMismatch TInt TBool
if 5 then 1 else 2
// Type error: ExpectedBool TInt
Ints, bools, strings (with ++), arithmetic (with unary minus), comparisons, conditionals
First-class functions, closures, application
String literals, concatenation, print statements, multi-statement files
Hindley-Milner inference with unification and occurs check
Variable bindings and recursive function definitions with letrec
Optional type annotations, parseInt/toString/show functions, interactive I/O, wildcards, sequencing
Lists, tuples, records, pattern matching, Maybe/Either error handling
List functions (map, filter, fold, zip), string functions (split, join, trim), 26 built-ins
readFile, writeFile, command-line arguments, practical scripting capabilities
Module system, imports/exports, math functions, more list/string operations
REPL, formatter, linter, IDE support, package manager