How to use the command 'ghcid' (with examples)
Ghcid is a minimalistic, command-line based Integrated Development Environment (CLI IDE) tailored for Haskell development. It offers real-time feedback by automatically reloading the Haskell code every time there is a change in the source files. This tool is invaluable for developers as it continuously displays compile errors, warnings, and test results, enabling a smooth and efficient workflow.
Use case 1: Start ghcid
and monitor a Haskell file for changes
Code:
ghcid path/to/Main.hs
Motivation:
Monitoring a single Haskell file for changes allows developers to focus on the currently active part of their project. By keeping an eye on a particular file, a developer can quickly identify and rectify any syntax or compilation errors as they work on their code. This helps in maintaining a smooth development process and ensures that code is always in a state ready for testing or deployment.
Explanation:
ghcid
: This command invokes the ghcid tool to start monitoring a file.path/to/Main.hs
: This specifies the path to the Haskell file you want to monitor. It tells ghcid which Haskell source file needs observation for any changes.
Example output:
✘ Errors:
Main.hs:10:11: error:
• Data constructor not in scope: SomeConstructor
• Perhaps you meant ‘SomeOtherConstructor’
Use case 2: Start ghcid
with a specific command, such as loading a Stack or Cabal project
Code:
ghcid --command "stack ghci Main.hs"
Motivation:
Many Haskell projects use build tools like Stack or Cabal for managing dependencies and building the project. Executing ghcid with a specific command allows developers to integrate these build tools, ensuring that their project is compiled within its configured environment. This is crucial for large projects with complex dependency trees that must be consistent across the development cycle.
Explanation:
--command
: This flag allows you to specify a custom command for ghcid to run."stack ghci Main.hs"
: This is the specific command being passed toghcid
. It uses Stack to load the Haskell fileMain.hs
into GHCi, Haskell’s interactive environment.
Example output:
All modules loaded: compliance check passed
Main.hs: no warnings
Use case 3: Run an action (default main
) on each file save
Code:
ghcid --run=action path/to/Main.hs
Motivation:
Automating the execution of a Haskell program or a specific command whenever a file is saved is a powerful feature for rapid development and testing. This ensures that after every change, the developer receives immediate feedback on how the code behaves, allowing them to make adjustments on the fly.
Explanation:
--run=action
: This instructs ghcid to execute a specific action (function or script) each time the file is saved.path/to/Main.hs
: As earlier, this sets the Haskell file that is under surveillance by ghcid.
Example output:
Running: action
Action complete: no errors encountered
Use case 4: Set maximum height and width (default to console height and width)
Code:
ghcid --height=40 --width=100 path/to/Main.hs
Motivation:
Sometimes developers prefer or require specific terminal dimensions to view outputs in a particular format. By customizing the terminal’s height and width, you can ensure that important information is not cut off or becomes unreadable, which is especially useful when dealing with complex error messages or extensive test results.
Explanation:
--height=40
: Sets the maximum height of the console window to 40 lines.--width=100
: Sets the width of the console output to 100 characters.path/to/Main.hs
: The file being monitored and compiled each time it is saved.
Example output:
[Screen limited to 40 lines and 100 characters wide]
✔ Compilation successful
Use case 5: Write full GHC compiler output to a file
Code:
ghcid --outputfile=path/to/output_file.txt path/to/Main.hs
Motivation:
Persisting compiler output in a file can be extremely beneficial for later review, audit trails, or sharing with team members for collaborative debugging. It ensures that no critical information is lost and provides a comprehensive record of the compilation process.
Explanation:
--outputfile=path/to/output_file.txt
: Determines the file where the GHC output will be saved.path/to/Main.hs
: The file that is being watched and compiled.
Example output:
Output written to path/to/output_file.txt
Use case 6: Execute REPL commands (eg. -- $> 1+1
) on each file save
Code:
ghcid --allow-eval path/to/Main.hs
Motivation:
Executing REPL (Read-Eval-Print Loop) commands automatically whenever a file is saved allows developers to run quick checks or computations directly, involving minimal friction. This can be particularly useful for evaluating expressions or checking the states of variables without explicitly entering a REPL environment at each update.
Explanation:
--allow-eval
: Enables evaluating expressions at each file save.path/to/Main.hs
: Specifies the file that is being actively monitored by the ghcid.
Example output:
$> 1+1
2
No errors found
Conclusion:
Ghcid proves to be an essential tool for Haskell developers, streamlining the coding process through its real-time monitoring and feedback mechanisms. From running specific project commands with Stack or Cabal to outputting detailed compiler logs, each use case caters to different aspects of the development workflow, making coding in Haskell both efficient and effective.