https://wiki.haskell.org/api.php?action=feedcontributions&user=Luzm&feedformat=atomHaskellWiki - User contributions [en]2024-03-29T00:50:56ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Haskell_in_industry&diff=34695Haskell in industry2010-05-10T09:04:37Z<p>Luzm: adding Circos Brand Karma</p>
<hr />
<div>__NOTOC__<br />
<br />
Haskell has a diverse range of use commercially, from aerospace and defense, to finance, to web startups, hardware design firms and lawnmower manufacturers. This page collects resources on the industrial use of Haskell.<br />
<br />
[http://industry.haskell.org/ http://industry.haskell.org/ihg-logo.png]<br />
<br />
In February 2009 the [http://industry.haskell.org/ Industrial Haskell Group] was launched to support the needs of commercial users of the Haskell programming language. Phase 2 of the effort, expanding membership to research groups and startups with smaller budgets, was [http://www.haskell.org/pipermail/haskell/2009-November/021734.html launched in November 2009]<br />
<br />
The main user conference for industrial Haskell use is CUFP - the [http://cufp.org/ Commercial Users of Functional Programming Workshop]. The annual conference is coming up in October 2010.<br />
<br />
== Industrial Haskell: 2009 status report ==<br />
<br />
===Industrial Haskell Group===<br />
<br />
For the first time, in 2009, a consortium of companies came together to fund continued development of Haskell and its toolchain. The result is the [http://industry.haskell.org IHG], [http://www.haskell.org/pipermail/haskell/2009-March/021060.html launched] earlier in the year. The initial round of funding resulted in [http://industry.haskell.org/status several improvements to the ecosystem.] The group is seeking to [http://industry.haskell.org/join expand membership in 2010] to further consolidate the commercial strength Haskell. The [http://www.vimeo.com/6697688 Birth of the IHG] was presented at the &quot;[http://cufp.galois.com/ Commercial Users of Functional Programming]&quot; workshop.<br />
<br />
===CUFP===<br />
<br />
This year's [http://cufp.galois.com/ Commercial Users of Haskell] workshop was held in Edinburgh, and included talks on [http://www.vimeo.com/6703480 Real World Haskell], [http://www.vimeo.com/6703480 teleconferencing on maps in Haskell], [http://www.vimeo.com/6699769 FP at Facebook]. Next year's CUFP will be held in Baltimore.<br />
<br />
===Industrial reports===<br />
<br />
As part of [http://galois.com Galois]' 10th birthday, Don Stewart presented a talk at the [http://www.londonhug.net/ LondonHUG] on [http://www.galois.com/blog/2009/04/27/engineering-large-projects-in-haskell-a-decade-of-fp-at-galois/ Engineering Large Projects in Haskell], celebrating a decade of use of Haskell by Galois. [http://www.typlab.com/ TypLAB], a new startup [http://blog.typlab.com/2009/09/why-we-use-haskell/ talked about why they use Haskell]. Facebook released its [http://github.com/facebook/lex-pass/tree/master lex-pass tool to automate changes to a PHP codebase, by writing abstract-syntax-tree transformers in Haskell]. And [http://www.starling-software.com/en/ Starling Software] described [http://www.starling-software.com/misc/icfp-2009-cjs.pdf building a real time financial trading system in Haskell] :: PDF. Tom Hawkin's [http://hackage.haskell.org/package/atom/ Atom EDSL] for control systems [http://www.haskell.org/pipermail/haskell-cafe/2009-July/064775.html went into production use] in trucks and buses, and is [http://www.haskell.org/pipermail/haskell-cafe/2009-December/070558.html starting to be used] on a NASA runtime monitoring project. The [http://www.cryptol.net Cryptol] release got [http://developers.slashdot.org/article.pl?sid=08/12/26/1725208 slashdotted]. [http://blog.tupil.com/building-commercial-haskell-applications/ Tupil.com] talked about their experiences building commercial web apps in Haskell.<br />
<br />
== Haskell in Industry ==<br />
<br />
* [http://cufp.galois.com/2007/abstracts.html#CyrilSchmidt ABN AMRO] Amsterdam, The Netherlands<br />
<br />
<blockquote><br />
ABN AMRO is an international bank headquartered in Amsterdam. For its<br />
investment banking activities it needs to measure the counterparty risk<br />
on portfolios of financial derivatives. </blockquote><br />
<br />
::ABN AMRO's [http://cufp.galois.com/2007/abstracts.html#CyrilSchmidt CUFP talk].<br />
<br />
* [http://www.aetion.com/ Aetion Technologies LLC] Columbus, Ohio<br />
<br />
<blockquote><br />
Aetion is a defense contractor whose applications use artificial intelligence.<br />
Rapidly changing priorities make it important to minimize the code impact of<br />
changes, which suits Haskell well. Aetion has developed three main projects in<br />
Haskell, all successful. Haskell's concise code was perhaps most important for<br />
rewriting: it made it practicable to throw away old code occasionally. DSELs<br />
allowed the AI to be specified very declaratively. <br />
</blockquote><br />
<br />
::Aetion's [http://cufp.galois.com/2006/slides/GaryMorris.pdf CUFP talk].<br />
<br />
* [http://www.amgen.com/ Amgen] Thousand Oaks, California<br />
<blockquote><br />
Amgen is a human therapeutics company in the biotechnology industry. Amgen pioneered the development of novel products based on advances in recombinant DNA and molecular biology and launched the biotechnology industry’s first blockbuster medicines.<br />
<br />
Amgen uses Haskell;<br />
<br />
* To rapidly build software to implement mathematical models and other complex, mathematically oriented applications<br />
* Provide a more mathematically rigorous validation of software<br />
* To break developers out of their software development rut by giving them a new way to think about software.<br />
</blockquote><br />
<br />
::Amgen's [http://cufp.galois.com/2008/abstracts.html#BalabanDavid CUFP talk].<br />
<br />
* [http://www.ansemond.com/ Ansemond LLC]<br />
<br />
<blockquote><br />
"Find It! Keep It! is a Mac Web Browser that lets you keep the pages you<br />
visit in a database. A list of these pages is shown in the 'database<br />
view'. "<br />
</blockquote><br />
<br />
* [http://antiope.com/ Antiope] Fair Haven, New Jersey<br />
<br />
<blockquote><br />
Antiope Associates provides custom solutions for wireless communication<br />
and networking problems. Our team has expertise in all aspects of<br />
wireless system design, from the physical and protocol layers to complex<br />
networked applications. Antiope Associates's relies on a number of<br />
advanced techniques to ensure that the communication systems we design<br />
are reliable and free from error. We use custom simulation tools<br />
developed in Haskell, to model our hardware designs..<br />
</blockquote><br />
<br />
::Antiope's [http://cufp.galois.com/2008/slides/WrightGregory.pdf CUFP talk].<br />
<br />
* [http://www.att.com AT&amp;T]<br />
<blockquote><br />
Haskell is being used in the Network Security division to automate processing of internet abuse complaints. Haskell has allowed us to easily meet very tight deadlines with reliable results.<br />
</blockquote><br />
<br />
* [http://www.anygma.com/ Anygma] Antwerp, Belgium<br />
<br />
<blockquote><br />
Anygma is a startup company focusing on generating easy-to-use tools for<br />
creating audio-visual 2D/3D content, in the area of entertainment,<br />
media, corporate communication and the internet. The company is closely<br />
related to [http://www.nazooka.com/ Nazooka], a niche player in the<br />
media industry, specialized in creating cross media concepts and<br />
communication solutions. Anygma is using Haskell to quickly build a<br />
prototype of its new content creation platform, targeted towards artists<br />
and designers. </blockquote><br />
<br />
* [http://www.baml.com/ Bank of America Merril Lynch]<br />
<br />
<blockquote>Haskell is being used for backend data transformation and loading.</blockquote><br />
<br />
* [http://www.haskell.org/communities/12-2007/html/report.html#sect7.1.2 Barclays Capital Quantitative Analytics Group]<br />
<br />
<blockquote><br />
Barclays Capital's Quantitative Analytics group is using Haskell to<br />
develop an embedded domain-specific functional language (called FPF)<br />
which is used to specify exotic equity derivatives. These derivatives,<br />
which are naturally best described in terms of mathematical functions,<br />
and constructed compositionally, map well to being expressed in an<br />
embedded functional language. This language is now regularly being used<br />
by people who had no previous functional language experience.<br />
</blockquote><br />
<br />
::[http://lambda-the-ultimate.org/node/3331 Simon Frankau et al's JFP paper on their use of Haskell]<br />
<br />
* [http://www.bcode.com/ bCODE Pty Ltd] Sydney Australia<br />
<blockquote><br />
bCode Pty Ltd is a small venture capital-funded startup using Ocaml and a bit of Haskell in Sydney Australia.<br />
</blockquote><br />
<br />
* [http://www.bluespec.com/ Bluespec, Inc.] Waltham, Massachusetts<br />
<br />
<blockquote><br />
Developing a modern integrated circuit (ASIC or FPGA) is an enormously<br />
expensive process involving specification, modeling (to choose and fix the<br />
architecture), design (to describe what will become silicon) and verification<br />
(to ensure that it meets the specs), all before actually committing anything to<br />
silicon (where the cost of a failure can be tens of millions of dollars).<br />
Bluespec, Inc. is a three year-old company that provides language facilities,<br />
methodologies, and tools for this purpose, within the framework of the IEEE<br />
standard languages SystemVerilog and SystemC, but borrowing ideas heavily from<br />
Term Rewriting Systems and functional programming languages like Haskell. In<br />
this talk, after a brief technical overview to set the context, we will<br />
describe our tactics and strategies, and the challenges we face, in introducing<br />
declarative programming ideas into this field, both externally (convincing<br />
customers about the value of these ideas) and internally (using Haskell for our<br />
tool implementation). <br />
</blockquote><br />
<br />
::Bluespec's [http://cufp.galois.com/2006/abstracts.html#RishiyurNikhil CUFP talk].<br />
<br />
<br />
* [http://www.circos.com Circos Brand Karma] Singapore<br />
<blockquote><br />
Brand Karma provides services to brand owners to measure online sentiments towards their brands.<br />
Haskell is used in building parts of the product, specifically for back-end job scheduling and brand matching.<br />
</blockquote><br />
<br />
<br />
* [http://www.credit-suisse.com/ Credit Suisse Global Modelling and Analytics Group] London, UK; New York City, New York<br />
<br />
<blockquote><br />
GMAG, the quantitative modelling group at Credit Suisse, has been using Haskell<br />
for various projects since the beginning of 2006, with the twin aims of<br />
improving the productivity of modellers and making it easier for other people<br />
within the bank to use GMAG models. Current projects include: Further work on<br />
tools for checking, manipulating and transforming spreadsheets; a<br />
domain-specific language embedded in Haskell for implementing reusable<br />
components that can be compiled into various target forms (see the video presentation: [http://www.londonhug.net/2008/08/11/video-paradise-a-dsel-for-derivatives-pricing/ Paradise, a DSEL for Derivatives Pricing]).<br />
</blockquote><br />
<br />
::Credit Suisse's [http://cufp.galois.com/2006/abstracts.html#HowardMansell CUFP talk].<br />
<br />
* [http://www.db.com/ Deutsche Bank Equity Proprietary Trading, Directional Credit Trading]<br />
<br />
<blockquote><br />
The Directional Credit Trading group uses Haskell as the primary<br />
implementation language for all its software infrastructure.<br />
</blockquote><br />
<br />
::Deutsche Bank's [http://cufp.galois.com/2008/abstracts.html#PolakowJeff CUFP talk].<br />
<br />
* [http://article.gmane.org/gmane.comp.lang.haskell.cafe/37093 Eaton] Cleveland, Ohio<br />
<br />
<blockquote><br />
Design and verification of hydraulic hybrid vehicle systems<br />
</blockquote><br />
<br />
::Eaton's [http://cufp.galois.com/2008/abstracts.html#HawkinsTom CUFP talk]<br />
::Eaton's [http://www.haskell.org/pipermail/haskell-cafe/2009-April/060602.html experiences using a Haskell DSL]<br />
<br />
* [http://facebook.com Facebook]<br />
<br />
<blockquote><br />
Facebook uses some Haskell internally for tools. [http://github.com/facebook/lex-pass/tree/master lex-pass] is a tool for programmatically manipulating a PHP code base via Haskell.<br />
</blockquote><br />
<br />
:: Facebook's [http://cufp.galois.com/2009/abstracts.html#ChristopherPiroEugeneLetuchy CUFP talk]<br />
<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2008-September/047168.html Gamr7] http://gamr7.com/ Lyon, France<br />
<br />
<blockquote><br />
Gamr7 is a startup focused on procedural city generation for the game<br />
and simulation market. <br />
</blockquote><br />
<br />
* [http://www.galois.com/ Galois, Inc] Portland, Oregon<br />
<br />
<blockquote><br />
Galois designs and develops high confidence software for critical applications.<br />
Our innovative approach to software development provides high levels of<br />
assurance, yet its scalability enables us to address the most complex problems.<br />
We have successfully engineered projects under contract for corporations and<br />
government clients in the demanding application areas of security, information<br />
assurance and cryptography. <br />
</blockquote><br />
<br />
::Galois' [http://cufp.galois.com/2007/abstracts.html#JohnLaunchbury CUFP talk]<br />
::Galois' [http://www.galois.com/blog/2009/04/27/engineering-large-projects-in-haskell-a-decade-of-fp-at-galois/ retrospective on 10 years of industrial Haskell use]<br />
<br />
* [http://glyde.com/ Glyde]<br />
<br />
<blockquote><br />
Glyde uses OCaml and Haskell for a few projects. Glyde uses Haskell for our client-side template source-to-source translator, which converts HAML-like view templates into JS code.<br />
</blockquote><br />
<br />
* [http://article.gmane.org/gmane.comp.lang.haskell.cafe/21951 HAppS LLC]<br />
<br />
<blockquote><br />
Open web development company. Now merged with [http://happstack.com/ happstack]<br />
</blockquote><br />
<br />
* [http://hustlerturf.com Hustler Turf Equipment] Hesston, Kansas<br />
<blockquote><br />
Designs, builds, and sells lawn mowers. We use quite a bit of Haskell, especially as a "glue language" for tying together data from different manufacturing-related systems. We also use it for some web apps that are deployed to our dealer network. There are also some uses for it doing sysadmin<br />
automation, such as adding/removing people from LDAP servers and the like<br />
</blockquote><br />
<br />
* [http://iba-cg.de/haskell.html iba Consulting Gesellschaft] - Intelligent business architecture for you. Leipzig, Germany<br />
<br />
<blockquote><br />
iba CG develops software for large companies: <br />
* risk analysis and reporting solution for power supply company; <br />
* contract management, assert management, booking and budgeting software for one of the worldwide leading accounting firm.<br />
</blockquote><br />
<br />
* [http://www.ics-ag.de/ Informatik Consulting Systems AG]<br />
<br />
<blockquote><br />
ICS AG developed a simulation and testing tool which based on a DSL (Domain Specific Language). The DSL is used for the description of architecture and behavior of distributed system components (event/message based, reactive). The compiler was written in Haskell (with target language Ada). The test system is used in some industrial projects.<br />
</blockquote><br />
<br />
* [http://www.ivu.de/uk/products/public-transport/ IVU Traffic Technologies AG]<br />
<blockquote><br />
The rostering group at IVU Traffic Technologies AG has been using Haskell to check rosters for compliance with EC regulations.<br />
<br />
Our implementation is based on an embedded DSL to combine the regulation’s single rules into a solver that not only decides on instances but, in the case of a faulty roster, finds an interpretation of the roster that is “favorable” in the sense that the error messages it entails are “helpful” in leading the dispatcher to the resolution of the issue at hand.<br />
<br />
The solver is both reliable (due to strong static typing and referential transparency — we have not experienced a failure in three years) and efficient (due to constraint propagation, a custom search strategy, and lazy evaluation).<br />
<br />
Our EC 561/2006 component is part of the IVU.crew software suite and as such is in wide-spread use all over Europe, both in planning and dispatch. So the next time you enter a regional bus, chances are that the driver’s roster was checked by Haskell.<br />
</blockquote><br />
<br />
* [http://www.janrain.com JanRain]<br />
<blockquote><br />
JanRain uses Haskell for network and web software.<br />
</blockquote><br />
<br />
* [http://www.linspire.com/ Linspire]<br />
<br />
<blockquote><br />
Linspire, Inc. has used functional programming since its inception in 2001,<br />
beginning with extensive use of O'Caml, with a steady shift to Haskell as its<br />
implementations and libraries have matured. Hardware detection, software<br />
packaging and CGI web page generation are all areas where we have used<br />
functional programming extensively. Haskell's feature set lets us replace much<br />
of our use of little languages (e.g., bash or awk) and two-level languages (C<br />
or C++ bound to an interpreted language), allowing for faster development,<br />
better code sharing and ultimately faster implementations. Above all, we value<br />
static type checking for minimizing runtime errors in applications that run in<br />
unknown environments and for wrapping legacy programs in strongly typed<br />
functions to ensure that we pass valid arguments. <br />
</blockquote><br />
<br />
::Linspire's [http://cufp.galois.com/2006/abstracts.html#CliffordBeshers CUFP talk]<br />
<br />
* [http://www.mitre.org/ MITRE]<br />
<blockquote><br />
MITRE uses Haskell for, amongst other things, the [http://hackage.haskell.org/package/cpsa analysis of cryptographic protocols].<br />
</blockquote><br />
<br />
* [http://ertos.nicta.com.au/research/sel4/ NICTA]<br />
<blockquote><br />
NICTA has used Haskell as part of a project to verify the L4 microkernel.<br />
</blockquote><br />
::[http://www.drdobbs.com/embedded/222400553 Read the Dr. Dobbs article on using Haskell and formal methods to verify a kernel]<br />
<br />
* [http://blog.openomy.com/2008/01/case-study-using-haskell-and-happs-for.html Openomy]<br />
<br />
<blockquote><br />
Openomy's API v2.0 is developed in Haskell, using the<br />
[http://www.happs.org/ HAppS] web platform.<br />
</blockquote><br />
<br />
* [http://www.patch-tag.com Patch-Tag: hosting for darcs]<br />
<blockquote><br />
Need somewhere to put your darcs code? Try us.<br />
<br />
Patch-Tag is built with [http://happstack.com happstack], the continuation of the project formerly known as HAppS.<br />
</blockquote><br />
<br />
* [http://www.peerium.com Peerium, Inc] Cambridge, Massachusetts<br />
<blockquote><br />
At Peerium, we're striving to bring a new level of quality and efficiency to online communication and collaboration within virtual communities, social networks, and business environments. We believe that a new environment that supports the effortless sharing of both information and software will enable a level of online cooperation far beyond current Web-based technologies -- modern programming techniques will enable the creation of more robust and more powerful programs within these environments. To this end, we're building a new software platform for direct, real-time communication and collaboration within graphically rich environments. Peerium is located in the heart of Harvard Square in Cambridge, Massachusetts.<br />
</blockquote><br />
<br />
* [http://www.qualcomm.com/ Qualcomm, Inc]<br />
<br />
<blockquote><br />
Qualcomm uses Haskell to generate Lua bindings to the BREW platform <br />
</blockquote><br />
<br />
* [http://www.renci.org/ Renaissaince Computing Institute], Chapel Hill, North Carolina<br />
<blockquote><br />
The Renaissance Computing Institute (RENCI), a multi-institutional organization, brings together multidisciplinary experts and advanced technological capabilities to address pressing research issues and to find solutions to complex problems that affect the quality of life in North Carolina, our nation and the world.<br />
<br />
Research scientists at RENCI have used Haskell for a number of projects, including [http://vis.renci.org/jeff/2009/08/26/open-sourcing-the-big-board/ The Big Board].<br />
</blockquote><br />
<br />
<br />
::RENCI's [http://cufp.galois.com/2009/abstracts.html#JeffersonHeard CUFP talk].<br />
<br />
* [http://www.signalicorp.com/index.htm Signali] Portland, Oregon<br />
<br />
<blockquote><br />
Signali Corp is a new custom hardware design company. Our chief products<br />
are custom IP cores targeted for embedded DSP and cryptographic<br />
applications. Our specialty is the design and implementation of<br />
computationally intensive, complex algorithms. The interfaces to each<br />
core are modular and can be very efficiently modified for your specific<br />
application. System-level integration and validation is crucial and is<br />
the majority of investment in a product.<br />
</blockquote><br />
<br />
* [http://www.standardchartered.com/home/en/index.html Standard Chartered]<br />
<br />
<blockquote><br />
Standard Chartered has a group using Haskell in finance.<br />
</blockquote><br />
<br />
* [http://seereason.org/ SeeReason Partners, LLC]<br />
<br />
<blockquote><br />
Clifford Beshers, David Fox and Jeremy Shaw have formed SeeReason<br />
Partners, LLC. Our plan is to deliver services over the internet, using<br />
Haskell to build our applications whenever possible. We have chosen<br />
primary mathematics skills as our domain, seeking to create a social<br />
networking site with games and activities that are both fun and<br />
educational.<br />
</blockquote><br />
<br />
* [http://www.starling-software.com/en/index.html Starling Software] Tokyo, Japan<br />
<blockquote><br />
Starling Software are developing a commercial automated options trading system <br />
in Haskell, and are migrating other parts of their software suite to<br />
Haskell.<br />
</blockquote><br />
<br />
::Starling Software's [http://www.starling-software.com/misc/icfp-2009-cjs.pdf experience building real time trading systems in Haskell] <br />
<br />
* [http://jp.linkedin.com/pub/simon-cranshaw/0/23a/414 Tsuru Capital] Tokyo, Japan<br />
<blockquote><br />
Tsuru Capital is operating an automated options trading system written in Haskell.<br />
</blockquote><br />
<br />
* [http://tupil.com/ Tupil] Utrecht, The Netherlands<br />
<br />
<blockquote><br />
Tupil is a Dutch company that builds software for clients, written in Haskell. Tupil uses Haskell for the speed in development and resulting software quality. The company is founded by Chris Eidhof and Eelco Lempsink.<br />
</blockquote><br />
<br />
:: Tupil's experience building [http://blog.tupil.com/building-commercial-haskell-applications/ commercial web apps in Haskell]<br />
<br />
* [http://typlab.com TypLAB] Amsterdam, The Netherlands<br />
<br />
<blockquote><br />
TypLAB investigates and develops new ways of creating and consuming online content.<br />
</blockquote><br />
<br />
:: TypLAB's blog on [http://blog.typlab.com/2009/09/why-we-use-haskell/ why they use Haskell]<br />
<br />
* [http://www.sensor-sense.nl Sensor Sense] Nijmegen, The Netherlands<br />
<br />
<blockquote><br />
Sensor Sense is offering high technology systems for gas measurements in the ''ppbv'' down to ''pptv'' range. We use Haskell for the embedded control software of our trace gas detectors.<br />
</blockquote><br />
<br />
<br />
If you're using Haskell commercially, please add your details here.<br />
<br />
== The Industrial Haskell Group ==<br />
<br />
The [http://industry.haskell.org/ Industrial Haskell Group (IHG)] is an organisation to support the needs of commercial users of the Haskell programming language. <br />
<br />
== Jobs and recruitment ==<br />
<br />
[[Jobs|Haskell jobs]].<br />
<br />
See also the [http://www.jobs-in-fp.org/ Jobs in Functional Programming] event.<br />
<br />
== Consultants ==<br />
<br />
[[Consultants]]<br />
<br />
== Commercial Users of Functional Programming Workshop ==<br />
<br />
[http://www.galois.com/cufp/ Commercial Users of Functional Programming]<br />
<br />
The goal of [http://www.galois.com/cufp/ CUFP] is to build a community<br />
for users of functional programming languages and technology, be they<br />
using functional languages in their professional lives, in an open<br />
source project (other than implementation of functional languages), as a<br />
hobby, or any combination thereof. In short: anyone who uses functional<br />
programming as a means, but not an end.<br />
<br />
[[Category:Community]]</div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=13318GHC/As a library (up to 6.8)2007-05-31T09:11:11Z<p>Luzm: </p>
<hr />
<div>[[Category:GHC]]<br />
<p style='font-size: xx-large; font-weight:bold; text-align: center'>Using GHC as a library</p><br />
__TOC__<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
More documentation is available on the GHC wiki: http://cvs.haskell.org/trac/ghc/wiki/Commentary/Compiler/API<br />
<br />
== Getting started ==<br />
You'll need a version of GHC (at least 6.5) that supports the GHC API. The [http://www.haskell.org/ghc/download.html GHC download page] offers stable releases and development versions; you can also use CVS ([http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html instructions]) or darcs (e.g., <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>).<br />
<br />
To use the GHC API you say <br />
<haskell><br />
import GHC<br />
</haskell><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>. This module exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the [http://darcs.haskell.org/ghc/compiler/main/GHC.hs source code] (somewhat documented). There are also other modules of interest as you do more special things.<br />
<br />
Here's an example main program that does it [[Media:Main.hs]] (good for GHC 6.6). You need to manually change the value of <tt>myGhcRoot</tt> to point to your GHC directory.<br />
<br />
To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
== Common use cases and functions ==<br />
<br />
'''Assumes GHC 6.6.'''<br />
<br />
=== Default exception handling ===<br />
<br />
If you don't handle exceptions yourself, you are recommended to wrap all code inside the wrapper:<br />
<haskell><br />
defaultErrorHandler :: DynFlags -> IO a -> IO a<br />
DynFlags.defaultDynFlags :: DynFlags<br />
</haskell><br />
This catches exceptions and prints out exception details and exits your program with exit code 1.<br />
<br />
Example:<br />
<haskell><br />
import GHC<br />
import DynFlags(defaultDynFlags)<br />
<br />
main = defaultErrorHandler defaultDynFlags $ do<br />
{-<br />
stuff in the following subsections<br />
-}<br />
</haskell><br />
<br />
You do not have to use <hask>defaultDynFlags</hask>, but it's the easiest starting point.<br />
<br />
=== Initialization ===<br />
<br />
First create a session: <br />
<haskell><br />
newSession :: GhcMode -- BatchCompile | Interactive | MkDepend | ...<br />
-> Maybe FilePath -- GHC installation directory<br />
-> IO Session -- your seesion; you will need it<br />
</haskell><br />
The path to your GHC installation directory (e.g., /usr/local/lib/ghc-6.6) is in practice mandatory, even though in theory marked as optional.<br />
<br />
The session is configurable by dynamic flags (GHC dynamic flags plus session state; think <tt>-O2</tt>, <tt>-fvia-C</tt>, <tt>-fglasgow-exts</tt>, <tt>-package</tt>). This can be done with:<br />
<haskell><br />
getSessionDynFlags :: Session -> IO DynFlags<br />
setSessionDynFlags :: Session<br />
-> DynFlags<br />
-> IO [PackageId] -- important iff dynamic-linking<br />
parseDynamicFlags :: DynFlags -- old flags<br />
-> [String] -- e.g., all or part of getArgs<br />
-> IO (DynFlags, [String]) -- new flags, unknown args<br />
</haskell><br />
The <hask>DynFlags</hask> record has a gazillion fields; ask ghci to show all of them. You can change them by hand, or use the parser (which implements the GHC command line format and does the Right Thing). But there is one you must note:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
hscTarget :: HscTarget } -- HscC | HscAsm | HscInterpreted | ...<br />
</haskell><br />
This corresponds to <tt>-fvia-C</tt>, <tt>-fasm</tt>, or interpreting. When the session needs to re-compile a module, this field controls how. The default is <hask>HscAsm</hask>, ''even in the interactive mode'', meaning the interactive mode may produce .hi and .o files too. If you want to follow GHCi in not doing that, you must set this field to <hask>HscInterpreted</hask> yourself. (On the other hand, it is fun to contemplate an interactive session that generates machine code upon your command.)<br />
<br />
<hask>setSessionDynFlags</hask> also sets up your session's awareness of the package database (without which you can't even use the Prelude), so even if you like the defaults, you should still call it. (Older code called <hask>PackageConfig.initPackages</hask> for this.)<br />
<br />
Examples:<br />
* vanilla compiler, use all defaults (rare but good start)<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
getSessionDynFlags session >>= setSessionDynFlags session<br />
</haskell><br />
* compiler with custom flags, easy with parser<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
(f1,b) <- parseDynamicFlags f0 ["-fglasgow-exts", "-O", "-package", "ghc", "-package Cabal",<br />
"foo", "-v", "bar"]<br />
-- b = ["foo", "bar"]; the other args are recognized<br />
-- in GHC 6.6 "-O" implies "-fvia-C", that kind of thing is automatic here too<br />
setSessionDynFlags session f1<br />
</haskell><br />
* interactive session with interpreter<br />
<haskell><br />
session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
setSessionDynFlags session f0{hscTarget = HscInterpreted}<br />
</haskell><br />
<br />
=== Load or compile modules ===<br />
<br />
To compile code or load modules, first set one or more targets, then call the <hask>load</hask> function.<br />
<haskell><br />
guessTarget :: String -- "filename.hs" or "filename.lhs" or "MyModule"<br />
-> Maybe Phase -- if not Nothing, specifies starting phase<br />
-> IO Target<br />
addTarget :: Session -> Target -> IO ()<br />
setTargets :: Session -> [Target] -> IO ()<br />
getTargets :: Session -> IO [Target]<br />
removeTarget :: Session -> TargetId -> IO ()<br />
load :: Session -> LoadHowMuch -> IO SuccessFlag<br />
data LoadHowMuch<br />
= LoadAllTargets<br />
| LoadUpTo ModuleName<br />
| LoadDependenciesOf ModuleName<br />
</haskell><br />
<br />
Loading or compiling produces temp directories and files, which can only be correctly cleaned up or kept (depending on temp file flags in <hask>DynFlags</hask>) with the wrapper:<br />
<haskell><br />
defaultCleanupHandler :: DynFlags -> IO a -> IO a<br />
</haskell><br />
Two factors constrain how much code should be wrapped. At the minimal, function calls such as <hask>load</hask> and <hask>depanal</hask> that potentially unlit or compile or link should be wrapped. At the maximal, the flags passed to <hask>defaultCleanupHandler</hask> should be identical to those set to the session, so practically the wrapping should be after setting up seesion flags.<br />
<br />
Example:<br />
<haskell><br />
t <- guessTarget "Main.hs" Nothing<br />
addTarget session t -- setTargets session [t] is also good<br />
f <- getSessionDynFlags session<br />
sf <- defaultCleanupHandler f (load session LoadAllTargets)<br />
case sf of Succeeded -> ...<br />
Failed -> ...<br />
</haskell><br />
<br />
Dependencies (both modules and packages) are processed automatically, and an executable is produced if appropriate, precisely like <tt>--make</tt>.<br />
<br />
Modules are compiled as per the <hask>hscTarget</hask> flag (<tt>-fasm</tt>, <tt>-fvia-C</tt>, or interpreter) in <hask>DynFlags</hask>, ''independent of GHC mode''.<br />
<br />
=== Interactive evaluation ===<br />
<br />
Interactive evaluation ala GHCi is done by <hask>runStmt</hask>. But first, this is always done under a current context, i.e., which modules are in scope. Most probably you want to have at least the Prelude and those you loaded in the previous section. How to manipulate the context:<br />
<haskell><br />
setContext :: Session<br />
-> [Module] -- their top levels will be visible<br />
-> [Module] -- their exports will be visible<br />
-> IO ()<br />
getContext :: Session -> IO ([Module], [Module])<br />
findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module<br />
mkModule :: PackageId -> ModuleName -> Module<br />
mkModuleName :: String -> ModuleName<br />
PackageConfig.stringToPackageId :: String -> PackageId<br />
</haskell><br />
Every module given to <hask>setContext</hask> must be either in a package known to the session or has been loaded as per the previous subsection. Example:<br />
<haskell><br />
-- equivalent to GHCi's :m Prelude Control.Monad *Main<br />
prelude <- findModule session (mkModuleName "Prelude") Nothing<br />
monad <- findModule session (mkModuleName "Control.Monad") Nothing<br />
usermod <- findModule session (mkModuleName "Main") Nothing -- we have loaded this<br />
setContext session [usermod] [prelude,monad]<br />
</haskell><br />
You can also be specific about packages. You can also use <hask>mkModule</hask> instead of <hask>findModule</hask>, or even some module query functions in the next subsection.<br />
<br />
Having set a useful context, we're now ready to evaluate.<br />
<haskell><br />
runStmt :: Session -> String -> IO RunResult<br />
data RunResult<br />
= RunOk [Name] -- names bound by the expression<br />
| RunFailed<br />
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception<br />
</haskell><br />
Example:<br />
<haskell><br />
runStmt session "let n = 2 + 2" -- n is bound<br />
runStmt session "n" -- 4 is printed (note "it" is bound)<br />
</haskell><br />
<br />
(Interactive evaluation works in BatchCompile mode too! There are still other subtle differences, so this is not recommended.)<br />
<br />
=== Type checking ===<br />
What if I want the type info from a module?<br />
<br />
Once the modules are loaded in the session, they are already type-checked.<br />
The type information of a loaded module are stored in a data-structure called <br />
<hask>ModuleInfo</hask>. To access the type information, we need to apply function <hask>getModuleInfo</hask> to the target module.<br />
<br />
<hask>ModuleInfo</hask> is defined as follows,<br />
<br />
<haskell><br />
data ModuleInfo = ModuleInfo {<br />
minf_type_env :: TypeEnv,<br />
minf_exports :: NameSet, -- ToDo, [AvailInfo] like ModDetails?<br />
minf_rdr_env :: Maybe GlobalRdrEnv, -- Nothing for a compiled/package mod<br />
minf_instances :: [Instance]<br />
#ifdef GHCI<br />
,minf_modBreaks :: ModBreaks <br />
#endif<br />
-- ToDo: this should really contain the ModIface too<br />
}<br />
</haskell><br />
The field <hask>minf_type_env</hask> is holding the type environment, of type <hask>TypeEnv</hask>, which is defined as,<br />
<haskell><br />
type TypeEnv = [TyThing]<br />
</haskell><br />
where TyThing can be an identifier, a class, a type constructor or a data constructor.<br />
<haskell><br />
data TyThing = AnId Id<br />
| ADataCon DataCon<br />
| ATyCon TyCon<br />
| AClass Class<br />
</haskell><br />
<br />
Recalling the running example in the previous subsection, note that the variable <hask>usermod</hask> captures the user-defined module "Main". <br />
We retrieve the module information of "Main" module and unfold the type environment out of it.<br />
<haskell><br />
mb_userModInfo <- getModuleInfo session usermod<br />
case mb_userModInfo of <br />
Just userModInfo -><br />
let userTyThings = modInfoTyThings userModInfo -- access the type environments<br />
userTys = [ (i, idType i) | (AnId i) <- userTyThings ] -- we are only interested in the declared ids and their (inferred) types. <br />
in ... -- do something with userTys<br />
Nothing -> return ()<br />
</haskell><br />
<br />
<br />
=== Queries ===<br />
<br />
<haskell><br />
-- Get module dependency graph<br />
getModuleGraph :: Session -> IO ModuleGraph -- ModuleGraph = [ModSummary]<br />
-- Get bindings<br />
getBindings :: Session -> IO [TyThing]<br />
</haskell><br />
<br />
=== Messages ===<br />
<br />
Compiler messages (including progress, warnings, errors) are controlled by verbosity and routed through a callback mechanism. These are fields in <hask>DynFlags</hask>:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
verbosity :: Int,<br />
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message -> IO () }<br />
</haskell><br />
<br />
The <hask>verbosity</hask> field corresponds to the command line <tt>-v</tt> flag; <hask>parseDynamicFlags</hask> is applicable. A low verbosity means <hask>log_action</hask> is seldom called.<br />
<br />
You can set the callback to your logger, like<br />
<haskell><br />
f <- getSessionDynFlags session<br />
setSessionDynFlags session f{log_action = my_log_action}<br />
</haskell><br />
This sets the session's logger, but it will not see exceptions.<br />
<br />
If you call <hask>defaultErrorHandler</hask> at the outermost, clearly its message logger has to be set separately:<br />
<haskell><br />
main = defaultErrorHandler defaultDynFlags{log_action = my_log_action} $ do ...<br />
</haskell><br />
This logger will see messages produced by <hask>defaultErrorHandler</hask> upon exceptions.<br />
<br />
== Interactive mode example ==<br />
<br />
The file [[Media:Interactive.hs]] (also requires [[Media:MyPrelude.hs]]) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.<br />
<br />
== Using the GHC library from inside GHCi ==<br />
<br />
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.<br />
<br />
<pre><br />
$ ghci -package ghc<br />
Prelude> :m + GHC PackageConfig<br />
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
Prelude GHC> setSessionDynFlags session =<< getSessionDynFlags session<br />
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]<br />
Prelude GHC> runStmt session "let add1 x = x + 1"<br />
Prelude GHC> runStmt session "add1 2"<br />
3<br />
</pre></div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=13317GHC/As a library (up to 6.8)2007-05-31T09:08:05Z<p>Luzm: </p>
<hr />
<div>[[Category:GHC]]<br />
<p style='font-size: xx-large; font-weight:bold; text-align: center'>Using GHC as a library</p><br />
__TOC__<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
More documentation is available on the GHC wiki: http://cvs.haskell.org/trac/ghc/wiki/Commentary/Compiler/API<br />
<br />
== Getting started ==<br />
You'll need a version of GHC (at least 6.5) that supports the GHC API. The [http://www.haskell.org/ghc/download.html GHC download page] offers stable releases and development versions; you can also use CVS ([http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html instructions]) or darcs (e.g., <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>).<br />
<br />
To use the GHC API you say <br />
<haskell><br />
import GHC<br />
</haskell><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>. This module exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the [http://darcs.haskell.org/ghc/compiler/main/GHC.hs source code] (somewhat documented). There are also other modules of interest as you do more special things.<br />
<br />
Here's an example main program that does it [[Media:Main.hs]] (good for GHC 6.6). You need to manually change the value of <tt>myGhcRoot</tt> to point to your GHC directory.<br />
<br />
To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
== Common use cases and functions ==<br />
<br />
'''Assumes GHC 6.6.'''<br />
<br />
=== Default exception handling ===<br />
<br />
If you don't handle exceptions yourself, you are recommended to wrap all code inside the wrapper:<br />
<haskell><br />
defaultErrorHandler :: DynFlags -> IO a -> IO a<br />
DynFlags.defaultDynFlags :: DynFlags<br />
</haskell><br />
This catches exceptions and prints out exception details and exits your program with exit code 1.<br />
<br />
Example:<br />
<haskell><br />
import GHC<br />
import DynFlags(defaultDynFlags)<br />
<br />
main = defaultErrorHandler defaultDynFlags $ do<br />
{-<br />
stuff in the following subsections<br />
-}<br />
</haskell><br />
<br />
You do not have to use <hask>defaultDynFlags</hask>, but it's the easiest starting point.<br />
<br />
=== Initialization ===<br />
<br />
First create a session: <br />
<haskell><br />
newSession :: GhcMode -- BatchCompile | Interactive | MkDepend | ...<br />
-> Maybe FilePath -- GHC installation directory<br />
-> IO Session -- your seesion; you will need it<br />
</haskell><br />
The path to your GHC installation directory (e.g., /usr/local/lib/ghc-6.6) is in practice mandatory, even though in theory marked as optional.<br />
<br />
The session is configurable by dynamic flags (GHC dynamic flags plus session state; think <tt>-O2</tt>, <tt>-fvia-C</tt>, <tt>-fglasgow-exts</tt>, <tt>-package</tt>). This can be done with:<br />
<haskell><br />
getSessionDynFlags :: Session -> IO DynFlags<br />
setSessionDynFlags :: Session<br />
-> DynFlags<br />
-> IO [PackageId] -- important iff dynamic-linking<br />
parseDynamicFlags :: DynFlags -- old flags<br />
-> [String] -- e.g., all or part of getArgs<br />
-> IO (DynFlags, [String]) -- new flags, unknown args<br />
</haskell><br />
The <hask>DynFlags</hask> record has a gazillion fields; ask ghci to show all of them. You can change them by hand, or use the parser (which implements the GHC command line format and does the Right Thing). But there is one you must note:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
hscTarget :: HscTarget } -- HscC | HscAsm | HscInterpreted | ...<br />
</haskell><br />
This corresponds to <tt>-fvia-C</tt>, <tt>-fasm</tt>, or interpreting. When the session needs to re-compile a module, this field controls how. The default is <hask>HscAsm</hask>, ''even in the interactive mode'', meaning the interactive mode may produce .hi and .o files too. If you want to follow GHCi in not doing that, you must set this field to <hask>HscInterpreted</hask> yourself. (On the other hand, it is fun to contemplate an interactive session that generates machine code upon your command.)<br />
<br />
<hask>setSessionDynFlags</hask> also sets up your session's awareness of the package database (without which you can't even use the Prelude), so even if you like the defaults, you should still call it. (Older code called <hask>PackageConfig.initPackages</hask> for this.)<br />
<br />
Examples:<br />
* vanilla compiler, use all defaults (rare but good start)<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
getSessionDynFlags session >>= setSessionDynFlags session<br />
</haskell><br />
* compiler with custom flags, easy with parser<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
(f1,b) <- parseDynamicFlags f0 ["-fglasgow-exts", "-O", "-package", "ghc", "-package Cabal",<br />
"foo", "-v", "bar"]<br />
-- b = ["foo", "bar"]; the other args are recognized<br />
-- in GHC 6.6 "-O" implies "-fvia-C", that kind of thing is automatic here too<br />
setSessionDynFlags session f1<br />
</haskell><br />
* interactive session with interpreter<br />
<haskell><br />
session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
setSessionDynFlags session f0{hscTarget = HscInterpreted}<br />
</haskell><br />
<br />
=== Load or compile modules ===<br />
<br />
To compile code or load modules, first set one or more targets, then call the <hask>load</hask> function.<br />
<haskell><br />
guessTarget :: String -- "filename.hs" or "filename.lhs" or "MyModule"<br />
-> Maybe Phase -- if not Nothing, specifies starting phase<br />
-> IO Target<br />
addTarget :: Session -> Target -> IO ()<br />
setTargets :: Session -> [Target] -> IO ()<br />
getTargets :: Session -> IO [Target]<br />
removeTarget :: Session -> TargetId -> IO ()<br />
load :: Session -> LoadHowMuch -> IO SuccessFlag<br />
data LoadHowMuch<br />
= LoadAllTargets<br />
| LoadUpTo ModuleName<br />
| LoadDependenciesOf ModuleName<br />
</haskell><br />
<br />
Loading or compiling produces temp directories and files, which can only be correctly cleaned up or kept (depending on temp file flags in <hask>DynFlags</hask>) with the wrapper:<br />
<haskell><br />
defaultCleanupHandler :: DynFlags -> IO a -> IO a<br />
</haskell><br />
Two factors constrain how much code should be wrapped. At the minimal, function calls such as <hask>load</hask> and <hask>depanal</hask> that potentially unlit or compile or link should be wrapped. At the maximal, the flags passed to <hask>defaultCleanupHandler</hask> should be identical to those set to the session, so practically the wrapping should be after setting up seesion flags.<br />
<br />
Example:<br />
<haskell><br />
t <- guessTarget "Main.hs" Nothing<br />
addTarget session t -- setTargets session [t] is also good<br />
f <- getSessionDynFlags session<br />
sf <- defaultCleanupHandler f (load session LoadAllTargets)<br />
case sf of Succeeded -> ...<br />
Failed -> ...<br />
</haskell><br />
<br />
Dependencies (both modules and packages) are processed automatically, and an executable is produced if appropriate, precisely like <tt>--make</tt>.<br />
<br />
Modules are compiled as per the <hask>hscTarget</hask> flag (<tt>-fasm</tt>, <tt>-fvia-C</tt>, or interpreter) in <hask>DynFlags</hask>, ''independent of GHC mode''.<br />
<br />
=== Interactive evaluation ===<br />
<br />
Interactive evaluation ala GHCi is done by <hask>runStmt</hask>. But first, this is always done under a current context, i.e., which modules are in scope. Most probably you want to have at least the Prelude and those you loaded in the previous section. How to manipulate the context:<br />
<haskell><br />
setContext :: Session<br />
-> [Module] -- their top levels will be visible<br />
-> [Module] -- their exports will be visible<br />
-> IO ()<br />
getContext :: Session -> IO ([Module], [Module])<br />
findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module<br />
mkModule :: PackageId -> ModuleName -> Module<br />
mkModuleName :: String -> ModuleName<br />
PackageConfig.stringToPackageId :: String -> PackageId<br />
</haskell><br />
Every module given to <hask>setContext</hask> must be either in a package known to the session or has been loaded as per the previous subsection. Example:<br />
<haskell><br />
-- equivalent to GHCi's :m Prelude Control.Monad *Main<br />
prelude <- findModule session (mkModuleName "Prelude") Nothing<br />
monad <- findModule session (mkModuleName "Control.Monad") Nothing<br />
usermod <- findModule session (mkModuleName "Main") Nothing -- we have loaded this<br />
setContext session [usermod] [prelude,monad]<br />
</haskell><br />
You can also be specific about packages. You can also use <hask>mkModule</hask> instead of <hask>findModule</hask>, or even some module query functions in the next subsection.<br />
<br />
Having set a useful context, we're now ready to evaluate.<br />
<haskell><br />
runStmt :: Session -> String -> IO RunResult<br />
data RunResult<br />
= RunOk [Name] -- names bound by the expression<br />
| RunFailed<br />
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception<br />
</haskell><br />
Example:<br />
<haskell><br />
runStmt session "let n = 2 + 2" -- n is bound<br />
runStmt session "n" -- 4 is printed (note "it" is bound)<br />
</haskell><br />
<br />
(Interactive evaluation works in BatchCompile mode too! There are still other subtle differences, so this is not recommended.)<br />
<br />
=== Type checking ===<br />
What if I want the type info from a module?<br />
<br />
Once the modules are loaded in the session, they are already type-checked.<br />
The type information of a loaded module are stored in a data-structure called <br />
<hask>ModuleInfo</hask>. To access the type information, we need to apply function <hask>getModuleInfo</hask> to the target module.<br />
<br />
<hask>ModuleInfo</hask> is defined as follows,<br />
<br />
<haskell><br />
data ModuleInfo = ModuleInfo {<br />
minf_type_env :: TypeEnv,<br />
minf_exports :: NameSet, -- ToDo, [AvailInfo] like ModDetails?<br />
minf_rdr_env :: Maybe GlobalRdrEnv, -- Nothing for a compiled/package mod<br />
minf_instances :: [Instance]<br />
#ifdef GHCI<br />
,minf_modBreaks :: ModBreaks <br />
#endif<br />
-- ToDo: this should really contain the ModIface too<br />
}<br />
</haskell><br />
The field <hask>minf_type_env</hask> is holding the type environment, of type <hask>TypeEnv</hask>, which is defined as,<br />
<haskell><br />
type TypeEnv = [TyThing]<br />
</haskell><br />
where TyThing can be an Id, a Class, a TyCon or a DataCon.<br />
<haskell><br />
data TyThing = AnId Id<br />
| ADataCon DataCon<br />
| ATyCon TyCon<br />
| AClass Class<br />
</haskell><br />
<br />
Recalling the running example in the previous subsection, we find that the variable <hask>usermod</hask> captures the user-defined module "Main", <br />
<br />
<haskell><br />
mb_userModInfo <- getModuleInfo session usermod<br />
case mb_userModInfo of <br />
Just userModInfo -><br />
let userTyThings = modInfoTyThings userModInfo -- access the type environments<br />
userTys = [ (i, idType i) | (AnId i) <- userTyThings ] -- we are only interested in the declared ids and their (inferred) types. <br />
in ... -- do something with userTys<br />
Nothing -> return ()<br />
</haskell><br />
<br />
<br />
=== Queries ===<br />
<br />
<haskell><br />
-- Get module dependency graph<br />
getModuleGraph :: Session -> IO ModuleGraph -- ModuleGraph = [ModSummary]<br />
-- Get bindings<br />
getBindings :: Session -> IO [TyThing]<br />
</haskell><br />
<br />
=== Messages ===<br />
<br />
Compiler messages (including progress, warnings, errors) are controlled by verbosity and routed through a callback mechanism. These are fields in <hask>DynFlags</hask>:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
verbosity :: Int,<br />
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message -> IO () }<br />
</haskell><br />
<br />
The <hask>verbosity</hask> field corresponds to the command line <tt>-v</tt> flag; <hask>parseDynamicFlags</hask> is applicable. A low verbosity means <hask>log_action</hask> is seldom called.<br />
<br />
You can set the callback to your logger, like<br />
<haskell><br />
f <- getSessionDynFlags session<br />
setSessionDynFlags session f{log_action = my_log_action}<br />
</haskell><br />
This sets the session's logger, but it will not see exceptions.<br />
<br />
If you call <hask>defaultErrorHandler</hask> at the outermost, clearly its message logger has to be set separately:<br />
<haskell><br />
main = defaultErrorHandler defaultDynFlags{log_action = my_log_action} $ do ...<br />
</haskell><br />
This logger will see messages produced by <hask>defaultErrorHandler</hask> upon exceptions.<br />
<br />
== Interactive mode example ==<br />
<br />
The file [[Media:Interactive.hs]] (also requires [[Media:MyPrelude.hs]]) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.<br />
<br />
== Using the GHC library from inside GHCi ==<br />
<br />
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.<br />
<br />
<pre><br />
$ ghci -package ghc<br />
Prelude> :m + GHC PackageConfig<br />
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
Prelude GHC> setSessionDynFlags session =<< getSessionDynFlags session<br />
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]<br />
Prelude GHC> runStmt session "let add1 x = x + 1"<br />
Prelude GHC> runStmt session "add1 2"<br />
3<br />
</pre></div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=13316GHC/As a library (up to 6.8)2007-05-31T08:59:48Z<p>Luzm: </p>
<hr />
<div>[[Category:GHC]]<br />
<p style='font-size: xx-large; font-weight:bold; text-align: center'>Using GHC as a library</p><br />
__TOC__<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
More documentation is available on the GHC wiki: http://cvs.haskell.org/trac/ghc/wiki/Commentary/Compiler/API<br />
<br />
== Getting started ==<br />
You'll need a version of GHC (at least 6.5) that supports the GHC API. The [http://www.haskell.org/ghc/download.html GHC download page] offers stable releases and development versions; you can also use CVS ([http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html instructions]) or darcs (e.g., <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>).<br />
<br />
To use the GHC API you say <br />
<haskell><br />
import GHC<br />
</haskell><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>. This module exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the [http://darcs.haskell.org/ghc/compiler/main/GHC.hs source code] (somewhat documented). There are also other modules of interest as you do more special things.<br />
<br />
Here's an example main program that does it [[Media:Main.hs]] (good for GHC 6.6). You need to manually change the value of <tt>myGhcRoot</tt> to point to your GHC directory.<br />
<br />
To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
== Common use cases and functions ==<br />
<br />
'''Assumes GHC 6.6.'''<br />
<br />
=== Default exception handling ===<br />
<br />
If you don't handle exceptions yourself, you are recommended to wrap all code inside the wrapper:<br />
<haskell><br />
defaultErrorHandler :: DynFlags -> IO a -> IO a<br />
DynFlags.defaultDynFlags :: DynFlags<br />
</haskell><br />
This catches exceptions and prints out exception details and exits your program with exit code 1.<br />
<br />
Example:<br />
<haskell><br />
import GHC<br />
import DynFlags(defaultDynFlags)<br />
<br />
main = defaultErrorHandler defaultDynFlags $ do<br />
{-<br />
stuff in the following subsections<br />
-}<br />
</haskell><br />
<br />
You do not have to use <hask>defaultDynFlags</hask>, but it's the easiest starting point.<br />
<br />
=== Initialization ===<br />
<br />
First create a session: <br />
<haskell><br />
newSession :: GhcMode -- BatchCompile | Interactive | MkDepend | ...<br />
-> Maybe FilePath -- GHC installation directory<br />
-> IO Session -- your seesion; you will need it<br />
</haskell><br />
The path to your GHC installation directory (e.g., /usr/local/lib/ghc-6.6) is in practice mandatory, even though in theory marked as optional.<br />
<br />
The session is configurable by dynamic flags (GHC dynamic flags plus session state; think <tt>-O2</tt>, <tt>-fvia-C</tt>, <tt>-fglasgow-exts</tt>, <tt>-package</tt>). This can be done with:<br />
<haskell><br />
getSessionDynFlags :: Session -> IO DynFlags<br />
setSessionDynFlags :: Session<br />
-> DynFlags<br />
-> IO [PackageId] -- important iff dynamic-linking<br />
parseDynamicFlags :: DynFlags -- old flags<br />
-> [String] -- e.g., all or part of getArgs<br />
-> IO (DynFlags, [String]) -- new flags, unknown args<br />
</haskell><br />
The <hask>DynFlags</hask> record has a gazillion fields; ask ghci to show all of them. You can change them by hand, or use the parser (which implements the GHC command line format and does the Right Thing). But there is one you must note:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
hscTarget :: HscTarget } -- HscC | HscAsm | HscInterpreted | ...<br />
</haskell><br />
This corresponds to <tt>-fvia-C</tt>, <tt>-fasm</tt>, or interpreting. When the session needs to re-compile a module, this field controls how. The default is <hask>HscAsm</hask>, ''even in the interactive mode'', meaning the interactive mode may produce .hi and .o files too. If you want to follow GHCi in not doing that, you must set this field to <hask>HscInterpreted</hask> yourself. (On the other hand, it is fun to contemplate an interactive session that generates machine code upon your command.)<br />
<br />
<hask>setSessionDynFlags</hask> also sets up your session's awareness of the package database (without which you can't even use the Prelude), so even if you like the defaults, you should still call it. (Older code called <hask>PackageConfig.initPackages</hask> for this.)<br />
<br />
Examples:<br />
* vanilla compiler, use all defaults (rare but good start)<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
getSessionDynFlags session >>= setSessionDynFlags session<br />
</haskell><br />
* compiler with custom flags, easy with parser<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
(f1,b) <- parseDynamicFlags f0 ["-fglasgow-exts", "-O", "-package", "ghc", "-package Cabal",<br />
"foo", "-v", "bar"]<br />
-- b = ["foo", "bar"]; the other args are recognized<br />
-- in GHC 6.6 "-O" implies "-fvia-C", that kind of thing is automatic here too<br />
setSessionDynFlags session f1<br />
</haskell><br />
* interactive session with interpreter<br />
<haskell><br />
session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
setSessionDynFlags session f0{hscTarget = HscInterpreted}<br />
</haskell><br />
<br />
=== Load or compile modules ===<br />
<br />
To compile code or load modules, first set one or more targets, then call the <hask>load</hask> function.<br />
<haskell><br />
guessTarget :: String -- "filename.hs" or "filename.lhs" or "MyModule"<br />
-> Maybe Phase -- if not Nothing, specifies starting phase<br />
-> IO Target<br />
addTarget :: Session -> Target -> IO ()<br />
setTargets :: Session -> [Target] -> IO ()<br />
getTargets :: Session -> IO [Target]<br />
removeTarget :: Session -> TargetId -> IO ()<br />
load :: Session -> LoadHowMuch -> IO SuccessFlag<br />
data LoadHowMuch<br />
= LoadAllTargets<br />
| LoadUpTo ModuleName<br />
| LoadDependenciesOf ModuleName<br />
</haskell><br />
<br />
Loading or compiling produces temp directories and files, which can only be correctly cleaned up or kept (depending on temp file flags in <hask>DynFlags</hask>) with the wrapper:<br />
<haskell><br />
defaultCleanupHandler :: DynFlags -> IO a -> IO a<br />
</haskell><br />
Two factors constrain how much code should be wrapped. At the minimal, function calls such as <hask>load</hask> and <hask>depanal</hask> that potentially unlit or compile or link should be wrapped. At the maximal, the flags passed to <hask>defaultCleanupHandler</hask> should be identical to those set to the session, so practically the wrapping should be after setting up seesion flags.<br />
<br />
Example:<br />
<haskell><br />
t <- guessTarget "Main.hs" Nothing<br />
addTarget session t -- setTargets session [t] is also good<br />
f <- getSessionDynFlags session<br />
sf <- defaultCleanupHandler f (load session LoadAllTargets)<br />
case sf of Succeeded -> ...<br />
Failed -> ...<br />
</haskell><br />
<br />
Dependencies (both modules and packages) are processed automatically, and an executable is produced if appropriate, precisely like <tt>--make</tt>.<br />
<br />
Modules are compiled as per the <hask>hscTarget</hask> flag (<tt>-fasm</tt>, <tt>-fvia-C</tt>, or interpreter) in <hask>DynFlags</hask>, ''independent of GHC mode''.<br />
<br />
=== Interactive evaluation ===<br />
<br />
Interactive evaluation ala GHCi is done by <hask>runStmt</hask>. But first, this is always done under a current context, i.e., which modules are in scope. Most probably you want to have at least the Prelude and those you loaded in the previous section. How to manipulate the context:<br />
<haskell><br />
setContext :: Session<br />
-> [Module] -- their top levels will be visible<br />
-> [Module] -- their exports will be visible<br />
-> IO ()<br />
getContext :: Session -> IO ([Module], [Module])<br />
findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module<br />
mkModule :: PackageId -> ModuleName -> Module<br />
mkModuleName :: String -> ModuleName<br />
PackageConfig.stringToPackageId :: String -> PackageId<br />
</haskell><br />
Every module given to <hask>setContext</hask> must be either in a package known to the session or has been loaded as per the previous subsection. Example:<br />
<haskell><br />
-- equivalent to GHCi's :m Prelude Control.Monad *Main<br />
prelude <- findModule session (mkModuleName "Prelude") Nothing<br />
monad <- findModule session (mkModuleName "Control.Monad") Nothing<br />
usermod <- findModule session (mkModuleName "Main") Nothing -- we have loaded this<br />
setContext session [usermod] [prelude,monad]<br />
</haskell><br />
You can also be specific about packages. You can also use <hask>mkModule</hask> instead of <hask>findModule</hask>, or even some module query functions in the next subsection.<br />
<br />
Having set a useful context, we're now ready to evaluate.<br />
<haskell><br />
runStmt :: Session -> String -> IO RunResult<br />
data RunResult<br />
= RunOk [Name] -- names bound by the expression<br />
| RunFailed<br />
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception<br />
</haskell><br />
Example:<br />
<haskell><br />
runStmt session "let n = 2 + 2" -- n is bound<br />
runStmt session "n" -- 4 is printed (note "it" is bound)<br />
</haskell><br />
<br />
(Interactive evaluation works in BatchCompile mode too! There are still other subtle differences, so this is not recommended.)<br />
<br />
=== Type checking ===<br />
What if I want the type info from a module?<br />
<br />
Once the modules are loaded in the session, they are already type-checked.<br />
The type information of a loaded module are stored in a data-structure called <br />
<hask>ModuleInfo</hask>. To access the type information, we need to apply function <hask>getModuleInfo</hask> to the target module.<br />
<br />
Recalling the running example in the previous subsection, we find that the variable <hask>usermod</hask> captures the user-defined module "Main", <br />
<br />
<haskell><br />
mb_userModInfo <- getModuleInfo session usermod<br />
case mb_userModInfo of <br />
Just userModInfo -><br />
let userTyThings = modInfoTyThings userModInfo -- access the type environments<br />
userTys = [ (i, idType i) | (AnId i) <- userTyThings ] -- we are only interested in the declared ids. <br />
in ... -- do something with userTys<br />
Nothing -> return ()<br />
</haskell><br />
<br />
<br />
=== Queries ===<br />
<br />
<haskell><br />
-- Get module dependency graph<br />
getModuleGraph :: Session -> IO ModuleGraph -- ModuleGraph = [ModSummary]<br />
-- Get bindings<br />
getBindings :: Session -> IO [TyThing]<br />
</haskell><br />
<br />
=== Messages ===<br />
<br />
Compiler messages (including progress, warnings, errors) are controlled by verbosity and routed through a callback mechanism. These are fields in <hask>DynFlags</hask>:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
verbosity :: Int,<br />
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message -> IO () }<br />
</haskell><br />
<br />
The <hask>verbosity</hask> field corresponds to the command line <tt>-v</tt> flag; <hask>parseDynamicFlags</hask> is applicable. A low verbosity means <hask>log_action</hask> is seldom called.<br />
<br />
You can set the callback to your logger, like<br />
<haskell><br />
f <- getSessionDynFlags session<br />
setSessionDynFlags session f{log_action = my_log_action}<br />
</haskell><br />
This sets the session's logger, but it will not see exceptions.<br />
<br />
If you call <hask>defaultErrorHandler</hask> at the outermost, clearly its message logger has to be set separately:<br />
<haskell><br />
main = defaultErrorHandler defaultDynFlags{log_action = my_log_action} $ do ...<br />
</haskell><br />
This logger will see messages produced by <hask>defaultErrorHandler</hask> upon exceptions.<br />
<br />
== Interactive mode example ==<br />
<br />
The file [[Media:Interactive.hs]] (also requires [[Media:MyPrelude.hs]]) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.<br />
<br />
== Using the GHC library from inside GHCi ==<br />
<br />
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.<br />
<br />
<pre><br />
$ ghci -package ghc<br />
Prelude> :m + GHC PackageConfig<br />
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
Prelude GHC> setSessionDynFlags session =<< getSessionDynFlags session<br />
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]<br />
Prelude GHC> runStmt session "let add1 x = x + 1"<br />
Prelude GHC> runStmt session "add1 2"<br />
3<br />
</pre></div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=13315GHC/As a library (up to 6.8)2007-05-31T08:55:33Z<p>Luzm: </p>
<hr />
<div>[[Category:GHC]]<br />
<p style='font-size: xx-large; font-weight:bold; text-align: center'>Using GHC as a library</p><br />
__TOC__<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
More documentation is available on the GHC wiki: http://cvs.haskell.org/trac/ghc/wiki/Commentary/Compiler/API<br />
<br />
== Getting started ==<br />
You'll need a version of GHC (at least 6.5) that supports the GHC API. The [http://www.haskell.org/ghc/download.html GHC download page] offers stable releases and development versions; you can also use CVS ([http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html instructions]) or darcs (e.g., <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>).<br />
<br />
To use the GHC API you say <br />
<haskell><br />
import GHC<br />
</haskell><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>. This module exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the [http://darcs.haskell.org/ghc/compiler/main/GHC.hs source code] (somewhat documented). There are also other modules of interest as you do more special things.<br />
<br />
Here's an example main program that does it [[Media:Main.hs]] (good for GHC 6.6). You need to manually change the value of <tt>myGhcRoot</tt> to point to your GHC directory.<br />
<br />
To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
== Common use cases and functions ==<br />
<br />
'''Assumes GHC 6.6.'''<br />
<br />
=== Default exception handling ===<br />
<br />
If you don't handle exceptions yourself, you are recommended to wrap all code inside the wrapper:<br />
<haskell><br />
defaultErrorHandler :: DynFlags -> IO a -> IO a<br />
DynFlags.defaultDynFlags :: DynFlags<br />
</haskell><br />
This catches exceptions and prints out exception details and exits your program with exit code 1.<br />
<br />
Example:<br />
<haskell><br />
import GHC<br />
import DynFlags(defaultDynFlags)<br />
<br />
main = defaultErrorHandler defaultDynFlags $ do<br />
{-<br />
stuff in the following subsections<br />
-}<br />
</haskell><br />
<br />
You do not have to use <hask>defaultDynFlags</hask>, but it's the easiest starting point.<br />
<br />
=== Initialization ===<br />
<br />
First create a session: <br />
<haskell><br />
newSession :: GhcMode -- BatchCompile | Interactive | MkDepend | ...<br />
-> Maybe FilePath -- GHC installation directory<br />
-> IO Session -- your seesion; you will need it<br />
</haskell><br />
The path to your GHC installation directory (e.g., /usr/local/lib/ghc-6.6) is in practice mandatory, even though in theory marked as optional.<br />
<br />
The session is configurable by dynamic flags (GHC dynamic flags plus session state; think <tt>-O2</tt>, <tt>-fvia-C</tt>, <tt>-fglasgow-exts</tt>, <tt>-package</tt>). This can be done with:<br />
<haskell><br />
getSessionDynFlags :: Session -> IO DynFlags<br />
setSessionDynFlags :: Session<br />
-> DynFlags<br />
-> IO [PackageId] -- important iff dynamic-linking<br />
parseDynamicFlags :: DynFlags -- old flags<br />
-> [String] -- e.g., all or part of getArgs<br />
-> IO (DynFlags, [String]) -- new flags, unknown args<br />
</haskell><br />
The <hask>DynFlags</hask> record has a gazillion fields; ask ghci to show all of them. You can change them by hand, or use the parser (which implements the GHC command line format and does the Right Thing). But there is one you must note:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
hscTarget :: HscTarget } -- HscC | HscAsm | HscInterpreted | ...<br />
</haskell><br />
This corresponds to <tt>-fvia-C</tt>, <tt>-fasm</tt>, or interpreting. When the session needs to re-compile a module, this field controls how. The default is <hask>HscAsm</hask>, ''even in the interactive mode'', meaning the interactive mode may produce .hi and .o files too. If you want to follow GHCi in not doing that, you must set this field to <hask>HscInterpreted</hask> yourself. (On the other hand, it is fun to contemplate an interactive session that generates machine code upon your command.)<br />
<br />
<hask>setSessionDynFlags</hask> also sets up your session's awareness of the package database (without which you can't even use the Prelude), so even if you like the defaults, you should still call it. (Older code called <hask>PackageConfig.initPackages</hask> for this.)<br />
<br />
Examples:<br />
* vanilla compiler, use all defaults (rare but good start)<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
getSessionDynFlags session >>= setSessionDynFlags session<br />
</haskell><br />
* compiler with custom flags, easy with parser<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
(f1,b) <- parseDynamicFlags f0 ["-fglasgow-exts", "-O", "-package", "ghc", "-package Cabal",<br />
"foo", "-v", "bar"]<br />
-- b = ["foo", "bar"]; the other args are recognized<br />
-- in GHC 6.6 "-O" implies "-fvia-C", that kind of thing is automatic here too<br />
setSessionDynFlags session f1<br />
</haskell><br />
* interactive session with interpreter<br />
<haskell><br />
session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
setSessionDynFlags session f0{hscTarget = HscInterpreted}<br />
</haskell><br />
<br />
=== Load or compile modules ===<br />
<br />
To compile code or load modules, first set one or more targets, then call the <hask>load</hask> function.<br />
<haskell><br />
guessTarget :: String -- "filename.hs" or "filename.lhs" or "MyModule"<br />
-> Maybe Phase -- if not Nothing, specifies starting phase<br />
-> IO Target<br />
addTarget :: Session -> Target -> IO ()<br />
setTargets :: Session -> [Target] -> IO ()<br />
getTargets :: Session -> IO [Target]<br />
removeTarget :: Session -> TargetId -> IO ()<br />
load :: Session -> LoadHowMuch -> IO SuccessFlag<br />
data LoadHowMuch<br />
= LoadAllTargets<br />
| LoadUpTo ModuleName<br />
| LoadDependenciesOf ModuleName<br />
</haskell><br />
<br />
Loading or compiling produces temp directories and files, which can only be correctly cleaned up or kept (depending on temp file flags in <hask>DynFlags</hask>) with the wrapper:<br />
<haskell><br />
defaultCleanupHandler :: DynFlags -> IO a -> IO a<br />
</haskell><br />
Two factors constrain how much code should be wrapped. At the minimal, function calls such as <hask>load</hask> and <hask>depanal</hask> that potentially unlit or compile or link should be wrapped. At the maximal, the flags passed to <hask>defaultCleanupHandler</hask> should be identical to those set to the session, so practically the wrapping should be after setting up seesion flags.<br />
<br />
Example:<br />
<haskell><br />
t <- guessTarget "Main.hs" Nothing<br />
addTarget session t -- setTargets session [t] is also good<br />
f <- getSessionDynFlags session<br />
sf <- defaultCleanupHandler f (load session LoadAllTargets)<br />
case sf of Succeeded -> ...<br />
Failed -> ...<br />
</haskell><br />
<br />
Dependencies (both modules and packages) are processed automatically, and an executable is produced if appropriate, precisely like <tt>--make</tt>.<br />
<br />
Modules are compiled as per the <hask>hscTarget</hask> flag (<tt>-fasm</tt>, <tt>-fvia-C</tt>, or interpreter) in <hask>DynFlags</hask>, ''independent of GHC mode''.<br />
<br />
=== Interactive evaluation ===<br />
<br />
Interactive evaluation ala GHCi is done by <hask>runStmt</hask>. But first, this is always done under a current context, i.e., which modules are in scope. Most probably you want to have at least the Prelude and those you loaded in the previous section. How to manipulate the context:<br />
<haskell><br />
setContext :: Session<br />
-> [Module] -- their top levels will be visible<br />
-> [Module] -- their exports will be visible<br />
-> IO ()<br />
getContext :: Session -> IO ([Module], [Module])<br />
findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module<br />
mkModule :: PackageId -> ModuleName -> Module<br />
mkModuleName :: String -> ModuleName<br />
PackageConfig.stringToPackageId :: String -> PackageId<br />
</haskell><br />
Every module given to <hask>setContext</hask> must be either in a package known to the session or has been loaded as per the previous subsection. Example:<br />
<haskell><br />
-- equivalent to GHCi's :m Prelude Control.Monad *Main<br />
prelude <- findModule session (mkModuleName "Prelude") Nothing<br />
monad <- findModule session (mkModuleName "Control.Monad") Nothing<br />
usermod <- findModule session (mkModuleName "Main") Nothing -- we have loaded this<br />
setContext session [usermod] [prelude,monad]<br />
</haskell><br />
You can also be specific about packages. You can also use <hask>mkModule</hask> instead of <hask>findModule</hask>, or even some module query functions in the next subsection.<br />
<br />
Having set a useful context, we're now ready to evaluate.<br />
<haskell><br />
runStmt :: Session -> String -> IO RunResult<br />
data RunResult<br />
= RunOk [Name] -- names bound by the expression<br />
| RunFailed<br />
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception<br />
</haskell><br />
Example:<br />
<haskell><br />
runStmt session "let n = 2 + 2" -- n is bound<br />
runStmt session "n" -- 4 is printed (note "it" is bound)<br />
</haskell><br />
<br />
(Interactive evaluation works in BatchCompile mode too! There are still other subtle differences, so this is not recommended.)<br />
<br />
=== Type checking ===<br />
What if I want the type info from a module?<br />
Once the modules are loaded in the session, they are already type-checked.<br />
The type information of a loaded module are stored in a data-structure called <br />
<hask>ModuleInfo</hask>. To access the type information, we need to apply function <hask>getModuleInfo</hask> to the target module.<br />
<br />
Recalling the running example in the previous subsection, we find that the variable <hask>usermod</hask> captures the user-defined module "Main", <br />
<br />
<haskell><br />
mb_userModInfo <- getModuleInfo session usermod<br />
case mb_userModInfo of <br />
Just userModInfo -><br />
let userTyThings = modInfoTyThings userModInfo -- access the type environments<br />
userTys = map (\tything -> case tything of -- we only want to access the declared ids. <br />
AnId i -> Just $ (tything, idType i) -- return the id tything and its type<br />
_ -> Nothing ) userTyThings<br />
in ... -- do something with userTys<br />
Nothing -> return ()<br />
</haskell><br />
<br />
<br />
=== Queries ===<br />
<br />
<haskell><br />
-- Get module dependency graph<br />
getModuleGraph :: Session -> IO ModuleGraph -- ModuleGraph = [ModSummary]<br />
-- Get bindings<br />
getBindings :: Session -> IO [TyThing]<br />
</haskell><br />
<br />
=== Messages ===<br />
<br />
Compiler messages (including progress, warnings, errors) are controlled by verbosity and routed through a callback mechanism. These are fields in <hask>DynFlags</hask>:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
verbosity :: Int,<br />
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message -> IO () }<br />
</haskell><br />
<br />
The <hask>verbosity</hask> field corresponds to the command line <tt>-v</tt> flag; <hask>parseDynamicFlags</hask> is applicable. A low verbosity means <hask>log_action</hask> is seldom called.<br />
<br />
You can set the callback to your logger, like<br />
<haskell><br />
f <- getSessionDynFlags session<br />
setSessionDynFlags session f{log_action = my_log_action}<br />
</haskell><br />
This sets the session's logger, but it will not see exceptions.<br />
<br />
If you call <hask>defaultErrorHandler</hask> at the outermost, clearly its message logger has to be set separately:<br />
<haskell><br />
main = defaultErrorHandler defaultDynFlags{log_action = my_log_action} $ do ...<br />
</haskell><br />
This logger will see messages produced by <hask>defaultErrorHandler</hask> upon exceptions.<br />
<br />
== Interactive mode example ==<br />
<br />
The file [[Media:Interactive.hs]] (also requires [[Media:MyPrelude.hs]]) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.<br />
<br />
== Using the GHC library from inside GHCi ==<br />
<br />
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.<br />
<br />
<pre><br />
$ ghci -package ghc<br />
Prelude> :m + GHC PackageConfig<br />
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
Prelude GHC> setSessionDynFlags session =<< getSessionDynFlags session<br />
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]<br />
Prelude GHC> runStmt session "let add1 x = x + 1"<br />
Prelude GHC> runStmt session "add1 2"<br />
3<br />
</pre></div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=13314GHC/As a library (up to 6.8)2007-05-31T08:52:04Z<p>Luzm: </p>
<hr />
<div>[[Category:GHC]]<br />
<p style='font-size: xx-large; font-weight:bold; text-align: center'>Using GHC as a library</p><br />
__TOC__<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
More documentation is available on the GHC wiki: http://cvs.haskell.org/trac/ghc/wiki/Commentary/Compiler/API<br />
<br />
== Getting started ==<br />
You'll need a version of GHC (at least 6.5) that supports the GHC API. The [http://www.haskell.org/ghc/download.html GHC download page] offers stable releases and development versions; you can also use CVS ([http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html instructions]) or darcs (e.g., <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>).<br />
<br />
To use the GHC API you say <br />
<haskell><br />
import GHC<br />
</haskell><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>. This module exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the [http://darcs.haskell.org/ghc/compiler/main/GHC.hs source code] (somewhat documented). There are also other modules of interest as you do more special things.<br />
<br />
Here's an example main program that does it [[Media:Main.hs]] (good for GHC 6.6). You need to manually change the value of <tt>myGhcRoot</tt> to point to your GHC directory.<br />
<br />
To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
== Common use cases and functions ==<br />
<br />
'''Assumes GHC 6.6.'''<br />
<br />
=== Default exception handling ===<br />
<br />
If you don't handle exceptions yourself, you are recommended to wrap all code inside the wrapper:<br />
<haskell><br />
defaultErrorHandler :: DynFlags -> IO a -> IO a<br />
DynFlags.defaultDynFlags :: DynFlags<br />
</haskell><br />
This catches exceptions and prints out exception details and exits your program with exit code 1.<br />
<br />
Example:<br />
<haskell><br />
import GHC<br />
import DynFlags(defaultDynFlags)<br />
<br />
main = defaultErrorHandler defaultDynFlags $ do<br />
{-<br />
stuff in the following subsections<br />
-}<br />
</haskell><br />
<br />
You do not have to use <hask>defaultDynFlags</hask>, but it's the easiest starting point.<br />
<br />
=== Initialization ===<br />
<br />
First create a session: <br />
<haskell><br />
newSession :: GhcMode -- BatchCompile | Interactive | MkDepend | ...<br />
-> Maybe FilePath -- GHC installation directory<br />
-> IO Session -- your seesion; you will need it<br />
</haskell><br />
The path to your GHC installation directory (e.g., /usr/local/lib/ghc-6.6) is in practice mandatory, even though in theory marked as optional.<br />
<br />
The session is configurable by dynamic flags (GHC dynamic flags plus session state; think <tt>-O2</tt>, <tt>-fvia-C</tt>, <tt>-fglasgow-exts</tt>, <tt>-package</tt>). This can be done with:<br />
<haskell><br />
getSessionDynFlags :: Session -> IO DynFlags<br />
setSessionDynFlags :: Session<br />
-> DynFlags<br />
-> IO [PackageId] -- important iff dynamic-linking<br />
parseDynamicFlags :: DynFlags -- old flags<br />
-> [String] -- e.g., all or part of getArgs<br />
-> IO (DynFlags, [String]) -- new flags, unknown args<br />
</haskell><br />
The <hask>DynFlags</hask> record has a gazillion fields; ask ghci to show all of them. You can change them by hand, or use the parser (which implements the GHC command line format and does the Right Thing). But there is one you must note:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
hscTarget :: HscTarget } -- HscC | HscAsm | HscInterpreted | ...<br />
</haskell><br />
This corresponds to <tt>-fvia-C</tt>, <tt>-fasm</tt>, or interpreting. When the session needs to re-compile a module, this field controls how. The default is <hask>HscAsm</hask>, ''even in the interactive mode'', meaning the interactive mode may produce .hi and .o files too. If you want to follow GHCi in not doing that, you must set this field to <hask>HscInterpreted</hask> yourself. (On the other hand, it is fun to contemplate an interactive session that generates machine code upon your command.)<br />
<br />
<hask>setSessionDynFlags</hask> also sets up your session's awareness of the package database (without which you can't even use the Prelude), so even if you like the defaults, you should still call it. (Older code called <hask>PackageConfig.initPackages</hask> for this.)<br />
<br />
Examples:<br />
* vanilla compiler, use all defaults (rare but good start)<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
getSessionDynFlags session >>= setSessionDynFlags session<br />
</haskell><br />
* compiler with custom flags, easy with parser<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
(f1,b) <- parseDynamicFlags f0 ["-fglasgow-exts", "-O", "-package", "ghc", "-package Cabal",<br />
"foo", "-v", "bar"]<br />
-- b = ["foo", "bar"]; the other args are recognized<br />
-- in GHC 6.6 "-O" implies "-fvia-C", that kind of thing is automatic here too<br />
setSessionDynFlags session f1<br />
</haskell><br />
* interactive session with interpreter<br />
<haskell><br />
session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
setSessionDynFlags session f0{hscTarget = HscInterpreted}<br />
</haskell><br />
<br />
=== Load or compile modules ===<br />
<br />
To compile code or load modules, first set one or more targets, then call the <hask>load</hask> function.<br />
<haskell><br />
guessTarget :: String -- "filename.hs" or "filename.lhs" or "MyModule"<br />
-> Maybe Phase -- if not Nothing, specifies starting phase<br />
-> IO Target<br />
addTarget :: Session -> Target -> IO ()<br />
setTargets :: Session -> [Target] -> IO ()<br />
getTargets :: Session -> IO [Target]<br />
removeTarget :: Session -> TargetId -> IO ()<br />
load :: Session -> LoadHowMuch -> IO SuccessFlag<br />
data LoadHowMuch<br />
= LoadAllTargets<br />
| LoadUpTo ModuleName<br />
| LoadDependenciesOf ModuleName<br />
</haskell><br />
<br />
Loading or compiling produces temp directories and files, which can only be correctly cleaned up or kept (depending on temp file flags in <hask>DynFlags</hask>) with the wrapper:<br />
<haskell><br />
defaultCleanupHandler :: DynFlags -> IO a -> IO a<br />
</haskell><br />
Two factors constrain how much code should be wrapped. At the minimal, function calls such as <hask>load</hask> and <hask>depanal</hask> that potentially unlit or compile or link should be wrapped. At the maximal, the flags passed to <hask>defaultCleanupHandler</hask> should be identical to those set to the session, so practically the wrapping should be after setting up seesion flags.<br />
<br />
Example:<br />
<haskell><br />
t <- guessTarget "Main.hs" Nothing<br />
addTarget session t -- setTargets session [t] is also good<br />
f <- getSessionDynFlags session<br />
sf <- defaultCleanupHandler f (load session LoadAllTargets)<br />
case sf of Succeeded -> ...<br />
Failed -> ...<br />
</haskell><br />
<br />
Dependencies (both modules and packages) are processed automatically, and an executable is produced if appropriate, precisely like <tt>--make</tt>.<br />
<br />
Modules are compiled as per the <hask>hscTarget</hask> flag (<tt>-fasm</tt>, <tt>-fvia-C</tt>, or interpreter) in <hask>DynFlags</hask>, ''independent of GHC mode''.<br />
<br />
=== Interactive evaluation ===<br />
<br />
Interactive evaluation ala GHCi is done by <hask>runStmt</hask>. But first, this is always done under a current context, i.e., which modules are in scope. Most probably you want to have at least the Prelude and those you loaded in the previous section. How to manipulate the context:<br />
<haskell><br />
setContext :: Session<br />
-> [Module] -- their top levels will be visible<br />
-> [Module] -- their exports will be visible<br />
-> IO ()<br />
getContext :: Session -> IO ([Module], [Module])<br />
findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module<br />
mkModule :: PackageId -> ModuleName -> Module<br />
mkModuleName :: String -> ModuleName<br />
PackageConfig.stringToPackageId :: String -> PackageId<br />
</haskell><br />
Every module given to <hask>setContext</hask> must be either in a package known to the session or has been loaded as per the previous subsection. Example:<br />
<haskell><br />
-- equivalent to GHCi's :m Prelude Control.Monad *Main<br />
prelude <- findModule session (mkModuleName "Prelude") Nothing<br />
monad <- findModule session (mkModuleName "Control.Monad") Nothing<br />
usermod <- findModule session (mkModuleName "Main") Nothing -- we have loaded this<br />
setContext session [usermod] [prelude,monad]<br />
</haskell><br />
You can also be specific about packages. You can also use <hask>mkModule</hask> instead of <hask>findModule</hask>, or even some module query functions in the next subsection.<br />
<br />
Having set a useful context, we're now ready to evaluate.<br />
<haskell><br />
runStmt :: Session -> String -> IO RunResult<br />
data RunResult<br />
= RunOk [Name] -- names bound by the expression<br />
| RunFailed<br />
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception<br />
</haskell><br />
Example:<br />
<haskell><br />
runStmt session "let n = 2 + 2" -- n is bound<br />
runStmt session "n" -- 4 is printed (note "it" is bound)<br />
</haskell><br />
<br />
(Interactive evaluation works in BatchCompile mode too! There are still other subtle differences, so this is not recommended.)<br />
<br />
=== Type checking ===<br />
What if I want the type info from a module?<br />
Once the modules are loaded in the session, they are already type-checked.<br />
The type information of a loaded module are stored in a data-structure called <br />
<hask>ModuleInfo</hask>. To access the type information, we need to use function <hask>getModuleInfo</hask>.<br />
<br />
Recalling the example in the previous subsection, we find that the variable <hask>usermod</hask> captures the user-defined module "Main", <br />
<br />
<haskell><br />
mb_userModInfo <- getModuleInfo session usermod<br />
case mb_userModInfo of <br />
Just userModInfo -><br />
let userTyThings = modInfoTyThings userModInfo -- access the type environments<br />
userTys = map (\tything -> case tything of -- we only want to access the declared ids. <br />
GHC.AnId i -> Just $ (tything, GHC.idType i)<br />
_ -> Nothing ) userTyThings<br />
in ... -- do something with userTys<br />
Nothing -> return ()<br />
</haskell><br />
<br />
<br />
=== Queries ===<br />
<br />
<haskell><br />
-- Get module dependency graph<br />
getModuleGraph :: Session -> IO ModuleGraph -- ModuleGraph = [ModSummary]<br />
-- Get bindings<br />
getBindings :: Session -> IO [TyThing]<br />
</haskell><br />
<br />
=== Messages ===<br />
<br />
Compiler messages (including progress, warnings, errors) are controlled by verbosity and routed through a callback mechanism. These are fields in <hask>DynFlags</hask>:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
verbosity :: Int,<br />
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message -> IO () }<br />
</haskell><br />
<br />
The <hask>verbosity</hask> field corresponds to the command line <tt>-v</tt> flag; <hask>parseDynamicFlags</hask> is applicable. A low verbosity means <hask>log_action</hask> is seldom called.<br />
<br />
You can set the callback to your logger, like<br />
<haskell><br />
f <- getSessionDynFlags session<br />
setSessionDynFlags session f{log_action = my_log_action}<br />
</haskell><br />
This sets the session's logger, but it will not see exceptions.<br />
<br />
If you call <hask>defaultErrorHandler</hask> at the outermost, clearly its message logger has to be set separately:<br />
<haskell><br />
main = defaultErrorHandler defaultDynFlags{log_action = my_log_action} $ do ...<br />
</haskell><br />
This logger will see messages produced by <hask>defaultErrorHandler</hask> upon exceptions.<br />
<br />
== Interactive mode example ==<br />
<br />
The file [[Media:Interactive.hs]] (also requires [[Media:MyPrelude.hs]]) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.<br />
<br />
== Using the GHC library from inside GHCi ==<br />
<br />
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.<br />
<br />
<pre><br />
$ ghci -package ghc<br />
Prelude> :m + GHC PackageConfig<br />
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
Prelude GHC> setSessionDynFlags session =<< getSessionDynFlags session<br />
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]<br />
Prelude GHC> runStmt session "let add1 x = x + 1"<br />
Prelude GHC> runStmt session "add1 2"<br />
3<br />
</pre></div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=13313GHC/As a library (up to 6.8)2007-05-31T08:48:24Z<p>Luzm: </p>
<hr />
<div>[[Category:GHC]]<br />
<p style='font-size: xx-large; font-weight:bold; text-align: center'>Using GHC as a library</p><br />
__TOC__<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
More documentation is available on the GHC wiki: http://cvs.haskell.org/trac/ghc/wiki/Commentary/Compiler/API<br />
<br />
== Getting started ==<br />
You'll need a version of GHC (at least 6.5) that supports the GHC API. The [http://www.haskell.org/ghc/download.html GHC download page] offers stable releases and development versions; you can also use CVS ([http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html instructions]) or darcs (e.g., <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>).<br />
<br />
To use the GHC API you say <br />
<haskell><br />
import GHC<br />
</haskell><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>. This module exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the [http://darcs.haskell.org/ghc/compiler/main/GHC.hs source code] (somewhat documented). There are also other modules of interest as you do more special things.<br />
<br />
Here's an example main program that does it [[Media:Main.hs]] (good for GHC 6.6). You need to manually change the value of <tt>myGhcRoot</tt> to point to your GHC directory.<br />
<br />
To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
== Common use cases and functions ==<br />
<br />
'''Assumes GHC 6.6.'''<br />
<br />
=== Default exception handling ===<br />
<br />
If you don't handle exceptions yourself, you are recommended to wrap all code inside the wrapper:<br />
<haskell><br />
defaultErrorHandler :: DynFlags -> IO a -> IO a<br />
DynFlags.defaultDynFlags :: DynFlags<br />
</haskell><br />
This catches exceptions and prints out exception details and exits your program with exit code 1.<br />
<br />
Example:<br />
<haskell><br />
import GHC<br />
import DynFlags(defaultDynFlags)<br />
<br />
main = defaultErrorHandler defaultDynFlags $ do<br />
{-<br />
stuff in the following subsections<br />
-}<br />
</haskell><br />
<br />
You do not have to use <hask>defaultDynFlags</hask>, but it's the easiest starting point.<br />
<br />
=== Initialization ===<br />
<br />
First create a session: <br />
<haskell><br />
newSession :: GhcMode -- BatchCompile | Interactive | MkDepend | ...<br />
-> Maybe FilePath -- GHC installation directory<br />
-> IO Session -- your seesion; you will need it<br />
</haskell><br />
The path to your GHC installation directory (e.g., /usr/local/lib/ghc-6.6) is in practice mandatory, even though in theory marked as optional.<br />
<br />
The session is configurable by dynamic flags (GHC dynamic flags plus session state; think <tt>-O2</tt>, <tt>-fvia-C</tt>, <tt>-fglasgow-exts</tt>, <tt>-package</tt>). This can be done with:<br />
<haskell><br />
getSessionDynFlags :: Session -> IO DynFlags<br />
setSessionDynFlags :: Session<br />
-> DynFlags<br />
-> IO [PackageId] -- important iff dynamic-linking<br />
parseDynamicFlags :: DynFlags -- old flags<br />
-> [String] -- e.g., all or part of getArgs<br />
-> IO (DynFlags, [String]) -- new flags, unknown args<br />
</haskell><br />
The <hask>DynFlags</hask> record has a gazillion fields; ask ghci to show all of them. You can change them by hand, or use the parser (which implements the GHC command line format and does the Right Thing). But there is one you must note:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
hscTarget :: HscTarget } -- HscC | HscAsm | HscInterpreted | ...<br />
</haskell><br />
This corresponds to <tt>-fvia-C</tt>, <tt>-fasm</tt>, or interpreting. When the session needs to re-compile a module, this field controls how. The default is <hask>HscAsm</hask>, ''even in the interactive mode'', meaning the interactive mode may produce .hi and .o files too. If you want to follow GHCi in not doing that, you must set this field to <hask>HscInterpreted</hask> yourself. (On the other hand, it is fun to contemplate an interactive session that generates machine code upon your command.)<br />
<br />
<hask>setSessionDynFlags</hask> also sets up your session's awareness of the package database (without which you can't even use the Prelude), so even if you like the defaults, you should still call it. (Older code called <hask>PackageConfig.initPackages</hask> for this.)<br />
<br />
Examples:<br />
* vanilla compiler, use all defaults (rare but good start)<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
getSessionDynFlags session >>= setSessionDynFlags session<br />
</haskell><br />
* compiler with custom flags, easy with parser<br />
<haskell><br />
session <- newSession BatchCompile (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
(f1,b) <- parseDynamicFlags f0 ["-fglasgow-exts", "-O", "-package", "ghc", "-package Cabal",<br />
"foo", "-v", "bar"]<br />
-- b = ["foo", "bar"]; the other args are recognized<br />
-- in GHC 6.6 "-O" implies "-fvia-C", that kind of thing is automatic here too<br />
setSessionDynFlags session f1<br />
</haskell><br />
* interactive session with interpreter<br />
<haskell><br />
session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
f0 <- getSessionDynFlags session<br />
setSessionDynFlags session f0{hscTarget = HscInterpreted}<br />
</haskell><br />
<br />
=== Load or compile modules ===<br />
<br />
To compile code or load modules, first set one or more targets, then call the <hask>load</hask> function.<br />
<haskell><br />
guessTarget :: String -- "filename.hs" or "filename.lhs" or "MyModule"<br />
-> Maybe Phase -- if not Nothing, specifies starting phase<br />
-> IO Target<br />
addTarget :: Session -> Target -> IO ()<br />
setTargets :: Session -> [Target] -> IO ()<br />
getTargets :: Session -> IO [Target]<br />
removeTarget :: Session -> TargetId -> IO ()<br />
load :: Session -> LoadHowMuch -> IO SuccessFlag<br />
data LoadHowMuch<br />
= LoadAllTargets<br />
| LoadUpTo ModuleName<br />
| LoadDependenciesOf ModuleName<br />
</haskell><br />
<br />
Loading or compiling produces temp directories and files, which can only be correctly cleaned up or kept (depending on temp file flags in <hask>DynFlags</hask>) with the wrapper:<br />
<haskell><br />
defaultCleanupHandler :: DynFlags -> IO a -> IO a<br />
</haskell><br />
Two factors constrain how much code should be wrapped. At the minimal, function calls such as <hask>load</hask> and <hask>depanal</hask> that potentially unlit or compile or link should be wrapped. At the maximal, the flags passed to <hask>defaultCleanupHandler</hask> should be identical to those set to the session, so practically the wrapping should be after setting up seesion flags.<br />
<br />
Example:<br />
<haskell><br />
t <- guessTarget "Main.hs" Nothing<br />
addTarget session t -- setTargets session [t] is also good<br />
f <- getSessionDynFlags session<br />
sf <- defaultCleanupHandler f (load session LoadAllTargets)<br />
case sf of Succeeded -> ...<br />
Failed -> ...<br />
</haskell><br />
<br />
Dependencies (both modules and packages) are processed automatically, and an executable is produced if appropriate, precisely like <tt>--make</tt>.<br />
<br />
Modules are compiled as per the <hask>hscTarget</hask> flag (<tt>-fasm</tt>, <tt>-fvia-C</tt>, or interpreter) in <hask>DynFlags</hask>, ''independent of GHC mode''.<br />
<br />
=== Interactive evaluation ===<br />
<br />
Interactive evaluation ala GHCi is done by <hask>runStmt</hask>. But first, this is always done under a current context, i.e., which modules are in scope. Most probably you want to have at least the Prelude and those you loaded in the previous section. How to manipulate the context:<br />
<haskell><br />
setContext :: Session<br />
-> [Module] -- their top levels will be visible<br />
-> [Module] -- their exports will be visible<br />
-> IO ()<br />
getContext :: Session -> IO ([Module], [Module])<br />
findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module<br />
mkModule :: PackageId -> ModuleName -> Module<br />
mkModuleName :: String -> ModuleName<br />
PackageConfig.stringToPackageId :: String -> PackageId<br />
</haskell><br />
Every module given to <hask>setContext</hask> must be either in a package known to the session or has been loaded as per the previous subsection. Example:<br />
<haskell><br />
-- equivalent to GHCi's :m Prelude Control.Monad *Main<br />
prelude <- findModule session (mkModuleName "Prelude") Nothing<br />
monad <- findModule session (mkModuleName "Control.Monad") Nothing<br />
usermod <- findModule session (mkModuleName "Main") Nothing -- we have loaded this<br />
setContext session [usermod] [prelude,monad]<br />
</haskell><br />
You can also be specific about packages. You can also use <hask>mkModule</hask> instead of <hask>findModule</hask>, or even some module query functions in the next subsection.<br />
<br />
Having set a useful context, we're now ready to evaluate.<br />
<haskell><br />
runStmt :: Session -> String -> IO RunResult<br />
data RunResult<br />
= RunOk [Name] -- names bound by the expression<br />
| RunFailed<br />
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception<br />
</haskell><br />
Example:<br />
<haskell><br />
runStmt session "let n = 2 + 2" -- n is bound<br />
runStmt session "n" -- 4 is printed (note "it" is bound)<br />
</haskell><br />
<br />
(Interactive evaluation works in BatchCompile mode too! There are still other subtle differences, so this is not recommended.)<br />
<br />
=== Type Checking ===<br />
<br />
Once the modules are loaded in the session, they are already type-checked.<br />
The type infos of a loaded module are stored in a data-structure called <br />
<hask>ModuleInfo</hask>.<br />
<br />
Recalling the example in the previous subsection, we find that the variable <hask>usermod</hask> captures the user-defined module "Main", we retrieve the module information,<br />
<br />
<haskell><br />
mb_userModInfo <- getModuleInfo session usermod<br />
case mb_userModInfo of <br />
Just userModInfo -><br />
let userTyThings = modInfoTyThings userModInfo -- access the type environments<br />
userTys = map (\tything -> case tything of -- we only want to access the declared ids. <br />
GHC.AnId i -> Just $ (tything, GHC.idType i)<br />
_ -> Nothing ) userTyThings<br />
in ... -- do something with userTys<br />
Nothing -> return ()<br />
</haskell><br />
<br />
<br />
=== Queries ===<br />
<br />
<haskell><br />
-- Get module dependency graph<br />
getModuleGraph :: Session -> IO ModuleGraph -- ModuleGraph = [ModSummary]<br />
-- Get bindings<br />
getBindings :: Session -> IO [TyThing]<br />
</haskell><br />
<br />
=== Messages ===<br />
<br />
Compiler messages (including progress, warnings, errors) are controlled by verbosity and routed through a callback mechanism. These are fields in <hask>DynFlags</hask>:<br />
<haskell><br />
data DynFlags = DynFlags { ...,<br />
verbosity :: Int,<br />
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message -> IO () }<br />
</haskell><br />
<br />
The <hask>verbosity</hask> field corresponds to the command line <tt>-v</tt> flag; <hask>parseDynamicFlags</hask> is applicable. A low verbosity means <hask>log_action</hask> is seldom called.<br />
<br />
You can set the callback to your logger, like<br />
<haskell><br />
f <- getSessionDynFlags session<br />
setSessionDynFlags session f{log_action = my_log_action}<br />
</haskell><br />
This sets the session's logger, but it will not see exceptions.<br />
<br />
If you call <hask>defaultErrorHandler</hask> at the outermost, clearly its message logger has to be set separately:<br />
<haskell><br />
main = defaultErrorHandler defaultDynFlags{log_action = my_log_action} $ do ...<br />
</haskell><br />
This logger will see messages produced by <hask>defaultErrorHandler</hask> upon exceptions.<br />
<br />
== Interactive mode example ==<br />
<br />
The file [[Media:Interactive.hs]] (also requires [[Media:MyPrelude.hs]]) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.<br />
<br />
== Using the GHC library from inside GHCi ==<br />
<br />
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.<br />
<br />
<pre><br />
$ ghci -package ghc<br />
Prelude> :m + GHC PackageConfig<br />
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")<br />
Prelude GHC> setSessionDynFlags session =<< getSessionDynFlags session<br />
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]<br />
Prelude GHC> runStmt session "let add1 x = x + 1"<br />
Prelude GHC> runStmt session "add1 2"<br />
3<br />
</pre></div>Luzmhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Data_structures&diff=4176Applications and libraries/Data structures2006-05-24T03:57:00Z<p>Luzm: </p>
<hr />
<div>{{unknown copyright}}<br />
{{LibrariesPage}}<br />
<br />
== Haskell Libraries and Tools for Data Structures ==<br />
<br />
;[http://www.eecs.tufts.edu/~rdocki01/edison.html Edison]<br />
:This is the latest version of the Edison library of efficient data structures. There are also [http://www.haskell.org/ghc/docs/edison/ earlier version of Edison] by Chris Okasaki. It provides sequences, finite maps, priority queues, and sets/bags. ([http://www.eecs.usma.edu/Personnel/okasaki/pubs.html#hw00 overview paper]).<br />
<br />
;[http://homepages.nildram.co.uk/~ahey/HLibs/Data.Tree.AVL/ Data.Tree.AVL]<br />
:An implementation of AVL trees and related utilities.<br />
<br />
;[http://homepages.nildram.co.uk/~ahey/HLibs/Data.StringMap/ Data.StringMap]<br />
:A library providing maps from String keys to values, based on Tries.<br />
<br />
;[http://www.cs.vu.nl/Strafunski/ Strafunski]<br />
:A bundle for generic programming. It provides programming support for generic traversal as useful in the implementation of program transformations.<br />
<br />
;[http://www.isi.edu/~hdaume/STPP/ The Haskell STate Preprocessor]<br />
:This is a short preprocessor for stateful Haskell programs. It aleviates the pain of performing single array lookup/write/update functions with some syntax to support it. It also supports hash table operations based on the HashTable implementation available from the author. Finally, it supports monadic if and monadic case constructions. It is lightweight in the sense that it performs no syntactic analysis and is essentially a character transformer.<br />
<br />
;[http://www.lochan.org/2005/keith-cl/libs/ Partial v0.1]<br />
:The Partial library provides a partial order class. It also provides routines for generating a Hasse diagram from a set and a partial order. Renderers are provided for the abstract Hasse diagram representation into LaTeX (via Xy-pic) and into dot, the format for AT&amp;T's Graphviz tools. Since no horizontal sorting is done, the Xy-pic output is rather poor at present; dot does a much better job with its layout optimisation algorithm.<br />
<br />
;[http://web.engr.oregonstate.edu/~erwig/diet/ Discrete Interval Encoding Trees]<br />
:The discrete interval encoding tree is a structure for storing subsets of types having a total order and a predecessor and a successor function.<br />
<br />
;[http://sourceforge.net/projects/ranged-sets/ Ranged Sets]<br />
:A ranged set is a list of non-overlapping ranges. The ranges have upper and lower boundaries, and a boundary divides the base type into values above and below. No value can ever sit on a boundary. So you can have the set {2.0 < x <= 3.0, 5.3 < x < 6}<br />
<br />
;[http://www.cwi.nl/~ralf/HList/ HList]<br />
:A heterogeneous collection is a datatype that is capable of storing data of different types, while providing operations for look-up, update, iteration, and others. There are various kinds of heterogeneous collections, differing in representation, invariants, and access operations.<br />
<br />
;[http://article.gmane.org/gmane.comp.lang.haskell.cafe/11230 Fast mutable variables for IO and ST]<br />
:Bulat Ziganshin's preliminary code for fast mutable variables in IO and ST.<br />
<br />
;[http://www.csee.ogi.edu/~diatchki/monadLib monadLib]<br />
:Iavor Diatchki's library of monad transformers for Haskell. It enables the quick construction of monads --- abstract data types that capture common programming idioms, such as throwing and catching exceptions or continuations. In many programming languages such features are built into the language (if they're provided at all), but in Haskell they are user-programmable.<br />
<br />
;[http://wiki.di.uminho.pt/wiki/bin/view/Alcino/PointlessHaskell Pointless Haskell]<br />
:Pointless Haskell is library for point-free programming with recursion patterns defined as hylomorphisms. It also allows the visualization of the intermediate data structure of the hylomorphisms with GHood. This feature together with the DrHylo tool allows us to easily visualize recursion trees of Haskell functions.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/haskell/ rhaskell : Reactive Objects]<br />
:Stefan Wehr's reactive objects library. Reactive objects are a convenient abstraction for writing programs which have to interact with a concurrent environment. A reactive object has two characteristics: the abandonment of all blocking operations and the unification of the concepts state and process. The former allows a reactive object to accept input from multiple sources without imposing any ordering on the input events. The latter prevents race conditions because the state of an object is only manipulated from the process belonging to the object.<br />
<br />
;[http://repetae.net/john/recent/out/GenUtil.html GenUtil]<br />
:A collection of random useful utility functions written in pure Haskell 98. In general, it trys to conform to the naming scheme put forth the Haskell prelude and fill in the obvious omissions, as well as provide useful routines in general.<br />
<br />
;[http://www.cs.uu.nl/~afie/pd09122004.zip PersistentDocument] ''The link is dead, somebody please either update it or remove it.''<br />
:The persistent document abstraction takes care of dealing with a document you want to open from and save to disk and that supports undo. This functionality can be used by editors of arbitrary documents and saves you a lot of quite subtle coding.<br />
<br />
;[[Zipper monad]]<br />
:A generic monad for navigating around arbitrary data structures<br />
<br />
=== Graphs ===<br />
<br />
;[http://web.engr.oregonstate.edu/~erwig/fgl/haskell/ FGL - A Functional Graph Library]<br />
:The functional graph library provides a collection of graph operations.<br />
<br />
;[http://wiki.di.uminho.pt/wiki/bin/view/PURe/PUReSoftware Data.Relation]<br />
:Part of the UMinho Haskell libraries, this library provides a representation and operations on relations. A special case of relations are graphs. The operations include graph chopping and slicing, strong connected component analysis, graphs metrics, and more.<br />
<br />
;[http://article.gmane.org/gmane.comp.lang.haskell.libraries/4739 Haskell Graph Automorphism Library]<br />
:Jean-Philippe Bernardy's implementation of Brendan McKay's algorithm for graph canonic labeling and automorphism group (Nauty).<br />
<br />
=== Strings ===<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/fps.html Fast Packed Strings]<br />
:The FPS library provides mmapped and malloc'd packed strings (byte arrays held by a ForeignPtr), along with a list interface to these strings. It lets you do extremely fast IO in Haskell; in some cases, even faster than typical C implementations, as well as conserving space.<br />
<br />
;[http://quux.org/devel/missingh MissingH]<br />
:MissingH is a library of pure-Haskell utility functions relating to strings, logging, and I/O.<br />
<br />
;[http://repetae.net/john/recent/out/HsLocale.html HsLocale]<br />
:A locale-aware replacement for the standard IO routines, and support for ''wide'' strings<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/code/icfp05/tests/unit-tests/VariableExpansion.hs VariableExpansion]<br />
:A library for variable expansion inside strings<br />
<br />
=== Serialising data ===<br />
<br />
;[http://www.n-heptane.com/nhlab/repos/NewBinary New binary]<br />
:A port of Malcolm Wallace's Binary library from NHC, offering facilities for heap compression and binary I/O. The de-facto standard for binary IO in Haskell<br />
<br />
;[http://www.cs.helsinki.fi/u/ekarttun/SerTH/ SerTH]<br />
:SerTH is a binary serialization library for Haskell. It supports serializing cyclic datatypes in a fast binary format. SerTH uses template haskell for deriving the serializing interface for new datatypes.<br />
<br />
;[http://freearc.narod.ru ByteStream]<br />
:ByteStream is like the NHC Binary library. It provides marshalling of Haskell objects to byte streams and restoring them back.<br />
<br />
=== Compressing data ===<br />
<br />
;[http://freearc.narod.ru/ Compression-2005]<br />
:Features of the Compression-2005 Library: <br />
* easy and uniform access to most competitive compression algorithms as of April?05: LZMA, PPMd and GRZip<br />
* all input/output performed via user-supplied functions (callbacks), so you can compress data in memory, files, pipes, sockets and anything else<br />
* all parameters of compression algorithm are defined with a single string, for example "lzma:8mb:fast:hc4:fb32".<br />
<br />
=== Benchmarking data structures ===<br />
<br />
;[http://www.cs.york.ac.uk/fp/auburn/ Auburn]<br />
:Auburn is Graeme Moss's kit for benchmarking implementations of lazy data structures. Give it several implementations of an ADT (abstract data type) and it will tell you which one is best for your particular application.<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/code/fps/tests/Bench.hs Bench]<br />
:Simple time and space benchmarking for various list-like data structures. Easily adapted to arbitrary structures</div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=3638GHC/As a library (up to 6.8)2006-04-12T08:36:18Z<p>Luzm: </p>
<hr />
<div>= Using GHC as a library =<br />
<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
== Getting started ==<br />
You'll need to get a version of GHC that supports the GHC API. Either download ghc from [http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html CVS] or use darcs: <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>. There are also [http://www.haskell.org/ghc/dist/current/dist nightly snapshot distributions] available.<br />
<br />
To use the GHC API you say simply <br />
<pre><br />
import GHC<br />
</pre><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>, which comes with GHC 6.5 and subsequent. The module GHC exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the source code (which is somewhat documented) here <br />
http://darcs.haskell.org/ghc/ghc/compiler/main/GHC.hs<br />
<br />
Here's an example main program that does it [[Media:Main.hs]]. To compile [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
----</div>Luzmhttps://wiki.haskell.org/index.php?title=GHC/As_a_library_(up_to_6.8)&diff=3637GHC/As a library (up to 6.8)2006-04-12T08:34:50Z<p>Luzm: </p>
<hr />
<div>= Using GHC as a library =<br />
<br />
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC. <br />
<br />
This page is a place for everyone to add<br />
* Notes about how to get it working<br />
* Comments about the API<br />
* Suggestions for improvement<br />
and so on.<br />
<br />
== Getting started ==<br />
You'll need to get a version of GHC that supports the GHC API. Either download ghc from [http://www.haskell.org/ghc/docs/latest/html/building/sec-cvs.html CVS] or use darcs: <tt>darcs get --partial http://darcs.haskell.org/ghc</tt>. There are also [http://www.haskell.org/ghc/dist/current/dist nightly snapshot distributions] available.<br />
<br />
To use the GHC API you say simply <br />
<pre><br />
import GHC<br />
</pre><br />
Doing this imports the module <tt>GHC</tt> from the package <tt>ghc</tt>, which comes with GHC 6.5 and subsequent. The module GHC exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the source code (which is somewhat documented) here <br />
http://darcs.haskell.org/ghc/ghc/compiler/main/GHC.hs<br />
<br />
Here's an example main program that does it [[Media:Main.hs]]. To compile in GHC 6.5 [[Media:Main.hs]], you have to turn on the flag "-package ghc", e.g.<br />
<pre><br />
ghc -package ghc Main.hs<br />
</pre><br />
<br />
----</div>Luzm