3 unstable releases
| 0.2.1 | Mar 16, 2026 |
|---|---|
| 0.2.0 | Mar 14, 2026 |
| 0.1.0 | Jul 23, 2023 |
#609 in Programming languages
82KB
2K
SLoC
ghci

A crate to manage and communicate with ghci sessions.
let mut ghci = Ghci::new()?;
let out = ghci.eval("putStrLn \"Hello world\"")?;
assert_eq!(out, "Hello world\n");
Platform support: Unix only (Linux, macOS, BSDs).
Features
Type conversions
Convert between Rust and Haskell values with ToHaskell / FromHaskell, and evaluate expressions directly into Rust types with eval_as:
use ghci::{Ghci, ToHaskell, FromHaskell};
let mut ghci = Ghci::new()?;
let x: i32 = ghci.eval_as("1 + 1")?;
assert_eq!(x, 2);
// Built-in support for common types
assert_eq!(true.to_haskell(), "True");
assert_eq!(Some(42u32).to_haskell(), "(Just 42)");
assert_eq!(vec![1u32, 2, 3].to_haskell(), "[1, 2, 3]");
Derive macros
With the derive feature, automatically derive conversions for your own types:
use ghci::{ToHaskell, FromHaskell};
#[derive(ToHaskell, FromHaskell)]
struct Point { x: u32, y: u32 }
// Point { x: 1, y: 2 } <-> "Point {x = 1, y = 2}"
#[derive(ToHaskell, FromHaskell)]
#[haskell(style = "app")]
struct Pair(u32, bool);
// Pair(1, true) <-> "(Pair 1 True)"
See the derive macro docs for all supported attributes (name, transparent, style, skip, bound).
Configuration
Use GhciBuilder to configure the ghci session:
use ghci::GhciBuilder;
let mut ghci = GhciBuilder::new()
.ghci_path("/usr/local/bin/ghci")
.arg("-XOverloadedStrings")
.working_dir("/path/to/project")
.build()?;
Timeouts
use std::time::Duration;
ghci.set_timeout(Some(Duration::from_secs(5)));
Shared sessions
SharedGhci provides a thread-safe, lazily-initialized session for use in tests:
use ghci::{Ghci, SharedGhci};
static GHCI: SharedGhci = SharedGhci::new(|| {
let mut ghci = Ghci::new()?;
ghci.import(&["Data.Char"])?;
Ok(ghci)
});
let mut ghci = GHCI.lock();
let out = ghci.eval("ord 'A'").unwrap();
assert_eq!(out, "65\n");
See the docs for the full API.
License
Copyright 2023 Basile Henry
Dependencies
~3MB
~63K SLoC