I've been doing some more work with atspkg and polyglot builds. It is now in slightly better shape, and it gives us the ability to call ATS code in Haskell almost painlessly.

Cabal Builds

Cabal is the common architectures for building and install Haskell libraries. It is sophisticated, accompanying a massive Cabal library. Since it's written in Haskell, it's relatively easy to just plug everything in.

We'll be using atspkg for our build, as usual. This will handle package management and dependency resolution for the ATS side of things. The main disadvantage is that your package's builds will be noticeably longer.

Our first step will be to prepare a polyglot project using pi:

pi git vmchale/haskell-ats ats-library cd ats-library/

Take it for a test drive with

cabal new-test cabal new-bench

You should see something exciting: the Haskell package builds with ATS dependencies! The Setup.hs file runs a build process defined by atspkg.dhall, installing the necessary compiler and any package dependencies.

Opening up atspkg.dhall, you should see the following:

let prelude = https://raw.githubusercontent.com/vmchale/atspkg/master/ats-pkg/dhall/atspkg-prelude.dhall

in prelude.default // { libraries = [ prelude.lib // { name = "ats-library" , src = [ "ats-src/ats-library.dats" ] , libTarget = "dist-newstyle/lib/libats-library.a" } ] }

This works in concert with the following in our .cabal file:

extra-source-files: ats-src/*.dats , dist-newstyle/lib/empty , atspkg.dhall

custom-setup setup-depends: base , ats-pkg >= 2.6.1.0 , Cabal

library hs-source-dirs: src

library extra-libraries: ats-library extra-lib-dirs: ./dist-newstyle/lib hs-source-dirs: src exposed-modules: Lib build-depends: base >= 4.7 && < 5 default-language: Haskell2010 if flag(development) ghc-options: -Werror if impl(ghc >= 8.0) ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat ghc-options: -Wall

And that's it! Our ATS source code now builds inside a Haskell package. We can even modify atspkg.dhall to add dependencies or multiple source files:

let prelude = https://raw.githubusercontent.com/vmchale/atspkg/master/ats-pkg/dhall/atspkg-prelude.dhall

in prelude.default // { libraries = [ prelude.lib // { name = "ats-library" , src = [ "ats-src/ats-library0.dats", "ats-src/ats-library1.dats" ] , libTarget = "dist-newstyle/lib/libats-library.a" } ] , dependencies = prelude.mapPlainDeps [ "atscntrb-hx-intinf" ] }

As you can see, this is a powerful tool for cross-language builds. I suspect that Haskell ecosystem will benefit immensely from such fluent, safe access to low-level functionality.