Esc
Start typing to search...

Jsonl Module

JSONL (JSON Lines) parsing and encoding.

The Jsonl module provides functions for converting between JSONL strings and Keel values. JSONL is a format where each line is an independent JSON object, commonly used for log files, event streams, and data pipelines.

Common patterns

import IO
import Jsonl
import Result

-- Parse a JSONL file
IO.readFile "events.jsonl"
  |> Result.andThen Jsonl.parse

-- Handle bad lines individually
IO.readFile "dirty.jsonl"
  |> Result.map Jsonl.parseAll

-- DataFrame round-trip
Jsonl.parseDataFrame input
  |> Result.map Jsonl.encodeDataFrame

Type mapping

Each JSONL line follows the same JSON mapping as the Json module:

JSONKeel
objectRecord
arrayList
stringString
number (int)Int
number (float)Float
booleanBool
nullUnit

Functions

Parsing

Jsonl.parse

String -> Result [a] String

Parse a JSONL string into a list of Keel values. Fails on the first malformed line.

Example:
import Jsonl

let result: Result [{ x: Int }] String =
    Jsonl.parse "{\"x\": 1}\n{\"x\": 2}"

-- Ok [{ x = 1 }, { x = 2 }]
Try it

Notes: Blank lines are skipped. On the first malformed line, returns Err with a "line N: " description. Use parseAll to collect per-line Results without failing fast.

See also: Jsonl.parseAll, Jsonl.encode, Json.parse

Jsonl.parseAll

String -> [Result a String]

Parse all lines in a JSONL string, returning a list of per-line Results. Malformed lines produce Err elements rather than aborting the parse.

Example:
import Jsonl

let results: [Result { x: Int } String] =
    Jsonl.parseAll "{\"x\": 1}\nnot json\n{\"x\": 3}"

-- [Ok { x = 1 }, Err "line 2: ...", Ok { x = 3 }]
Try it

Notes: Blank lines are skipped. Each Err carries a "line N: " description. Use List.filterMap or List.partition to separate good and bad lines.

See also: Jsonl.parse, Jsonl.mapLines

Jsonl.parseDataFrame

String -> Result DataFrame String

Parse a JSONL string into a DataFrame. Each line must be a JSON object; column types are inferred from all lines.

Example:
import Jsonl
import DataFrame

let df = Jsonl.parseDataFrame "{\"x\": 1}\n{\"x\": 2}"

-- Ok <DataFrame>
Try it

Notes: Returns Err if the input is empty or if column types are inconsistent across lines. Compose with IO.readFile via Result.andThen for file-based workflows.

See also: Jsonl.encodeDataFrame, Jsonl.parse, DataFrame.readJson

Encoding

Jsonl.encode

[a] -> String

Encode a list of Keel values as a JSONL string. Each element becomes one JSON line.

Example:
import Jsonl

Jsonl.encode [{ x = 1 }, { x = 2 }]

-- "{\"x\":1}\n{\"x\":2}"
Try it

Notes: Empty list produces an empty string. Records become JSON objects. Lists become JSON arrays.

See also: Jsonl.parse, Jsonl.encodeDataFrame

Jsonl.encodeDataFrame

DataFrame -> String

Encode a DataFrame as a JSONL string. Each row becomes one JSON object line.

Example:
import Jsonl
import DataFrame

let df = DataFrame.fromRecords [{ x = 1 }, { x = 2 }]
Jsonl.encodeDataFrame df

-- "{\"x\":1}\n{\"x\":2}"
Try it

See also: Jsonl.parseDataFrame, Jsonl.encode

Transform

Jsonl.mapLines

(Result a String -> b) -> String -> [b]

Transform each non-blank line through a callback. The callback receives a Result — Ok with the parsed value, or Err with a line-number-prefixed error message.

Example:
import Jsonl

fn extractX : Result { x: Int } String -> Maybe Int
fn extractX r =
    case r of
        Ok rec -> Just rec.x
        Err _ -> Nothing

Jsonl.mapLines extractX "{\"x\": 1}\nnot json\n{\"x\": 3}"

-- [Just 1, Nothing, Just 3]
Try it

Notes: Every non-blank line is mapped — the output list length equals the number of non-blank input lines. Use List.filterMap to drop Nothing/Err values after mapping.

See also: Jsonl.parseAll, Jsonl.parse