diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,55 +1,79 @@
-# NB: don't set `language: haskell` here
+language: c
+sudo: false
 
-# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.
-env:
-# - GHCVER=6.12.3
-# - GHCVER=7.0.1
-# - GHCVER=7.0.2
-# - GHCVER=7.0.3
-# - GHCVER=7.0.4
-# - GHCVER=7.2.1
-# - GHCVER=7.2.2
-# - GHCVER=7.4.1
- - GHCVER=7.4.2
-# - GHCVER=7.6.1
-# - GHCVER=7.6.2
- - GHCVER=7.6.3
-# - GHCVER=7.8.1 # see note about Alex/Happy
- - GHCVER=7.8.2 # see note about Alex/Happy
-# - GHCVER=head  # see section about GHC HEAD snapshots
+cache:
+  directories:
+    - $HOME/.cabsnap
+    - $HOME/.cabal/packages
 
-# Note: the distinction between `before_install` and `install` is not important.
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
+
+matrix:
+  include:
+    - env: CABALVER=1.16 GHCVER=7.6.3
+      compiler: ": #GHC 7.6.3"
+      addons: {apt: {packages: [cabal-install-1.16,ghc-7.6.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.8.3 COVERAGE=1
+      compiler: ": #GHC 7.8.3"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.2
+      compiler: ": #GHC 7.10.2"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+
 before_install:
- - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
- - travis_retry sudo apt-get update
- - travis_retry sudo apt-get install cabal-install-1.18 ghc-$GHCVER # see note about happy/alex
- - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH
- - |
-   if [ $GHCVER = "head" ] || [ ${GHCVER%.*} = "7.8" ]; then
-     travis_retry sudo apt-get install happy-1.19.3 alex-3.1.3
-     export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.3/bin:$PATH
+ - unset CC
+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:/opt/alex/3.1.4/bin:/opt/happy/1.19.5/bin:$PATH
+
+install:
+ - cabal --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
+   then
+     zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
+          $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
+   fi
+ - travis_retry cabal update -v
+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
+ - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
+
+# check whether current requested install-plan matches cached package-db snapshot
+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;
+   then
+     echo "cabal build-cache HIT";
+     rm -rfv .ghc;
+     cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
+     cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
    else
-     travis_retry sudo apt-get install happy alex
+     echo "cabal build-cache MISS";
+     rm -rf $HOME/.cabsnap;
+     mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
+     cabal install --only-dependencies --enable-tests --enable-benchmarks;
    fi
 
-install:
- - cabal update
- - cabal install --only-dependencies --enable-tests -v2  # -v2 provides useful information for debugging
+# snapshot package-db on cache miss
+ - if [ ! -d $HOME/.cabsnap ];
+   then
+      echo "snapshotting package-db to build-cache";
+      mkdir $HOME/.cabsnap;
+      cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
+      cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
+   fi
 
-# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.
+# Here starts the actual work to be performed for the package under test;
+# any command which exits with a non-zero exit code causes the build to fail.
 script:
- - cabal configure --enable-tests -v2  # -v2 provides useful information for debugging
+ - if [ -f configure.ac ]; then autoreconf -i; fi
+ - cabal configure --enable-tests --enable-benchmarks -v2 $([ "$COVERAGE" = "1" ] && echo "--enable-library-coverage") # -v2 provides useful information for debugging
  - cabal build   # this builds all libraries and executables (including tests/benchmarks)
  - cabal test
  - cabal check
  - cabal sdist   # tests that a source-distribution can be generated
 
-# The following scriptlet checks that the resulting source distribution can be built & installed
- - export SRC_TGZ=$(cabal-1.18 info . | awk '{print $2 ".tar.gz";exit}') ;
-   cd dist/;
-   if [ -f "$SRC_TGZ" ]; then
-      cabal install "$SRC_TGZ";
-   else
-      echo "expected '$SRC_TGZ' not found";
-      exit 1;
-   fi
+# Check that the resulting source distribution can be built & installed.
+# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
+# `cabal install --force-reinstalls dist/*-*.tar.gz`
+ - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
+   (cd dist && cabal install --force-reinstalls "$SRC_TGZ")
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,9 @@
+Changes since the 0.0.7 release
+-------------------------------
+
+* "→" can be used instead of "->"
+* GHC-7.10 support
+
 Changes since the 0.0.6 release
 -------------------------------
 
diff --git a/CPL.cabal b/CPL.cabal
--- a/CPL.cabal
+++ b/CPL.cabal
@@ -1,5 +1,5 @@
 Name:		CPL
-Version:	0.0.7
+Version:	0.0.8
 License:	BSD3
 License-File:	COPYING
 Author:		Masahiro Sakai (masahiro.sakai@gmail.com)
@@ -11,6 +11,7 @@
 Extra-Source-Files:
    README.markdown,
    CHANGELOG.markdown,
+   appveyor.yml,
    .travis.yml,
    samples/ack.cpl,
    samples/automata.cdt,
@@ -23,7 +24,12 @@
    samples/benchmark.cpl,
    samples/ack_3_4.cpl,
    samples/function.cpl,
-   src/CDT.hs-boot
+   src/CDT.hs-boot,
+   windows/COPYING.rtf,
+   windows/CPL.wxs,
+   windows/build_msi.hs,
+   windows/build_zip.hs,
+   build_bdist_linux.sh
 Build-Type: Simple
 
 source-repository head
@@ -38,6 +44,11 @@
   Description: Use Haskeline
   Default: True
 
+Flag LinuxStatic
+  Description: build statically linked binaries
+  Default: False
+  Manual: True
+
 Executable cpl
   Main-is: Main.hs
   HS-Source-Dirs: src
@@ -52,3 +63,5 @@
     if flag(Haskeline)
       CPP-Options: "-DUSE_HASKELINE_PACKAGE"
       Build-Depends: haskeline
+  if flag(LinuxStatic)
+    GHC-Options: -static -optl-static -optl-pthread
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,7 +1,7 @@
 An implementation of "A Categorical Programing Language"
 ========================================================
 
-[![Build Status](https://secure.travis-ci.org/msakai/cpl.png?branch=master)](http://travis-ci.org/msakai/cpl)
+[![Build Status](https://secure.travis-ci.org/msakai/cpl.png?branch=master)](http://travis-ci.org/msakai/cpl) [![Build status](https://ci.appveyor.com/api/projects/status/dl935ws9jouy06br/branch/master?svg=true)](https://ci.appveyor.com/project/msakai/cpl/branch/master) [![Hackage](https://budueba.com/hackage/CPL)](https://hackage.haskell.org/package/CPL)
 
 This package is an implementation of "A Categorical Programing Language"
 (CPL for short)[1][2] written in Haskell.
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,56 @@
+platform:
+- x86
+- x64
+
+install:
+- ps: |
+    # This is necessary because AppVeyor uses 64 bit environemnt even if "platform: x86" is specified.
+    # see also <http://help.appveyor.com/discussions/questions/213-platform-x86-is-not-32-bit>
+    if ("x86".Equals(${env:PLATFORM})) {
+      $env:HPChocoOptions = "--x86"
+      $env:HPPath = "${env:ProgramFiles(x86)}\Haskell Platform\7.10.3"
+      Invoke-WebRequest -Uri https://haskell.org/platform/download/7.10.3/HaskellPlatform-7.10.3-i386-setup.exe -OutFile HaskellPlatform-7.10.3-i386-setup.exe
+      .\HaskellPlatform-7.10.3-i386-setup.exe /S
+    } else {
+      $env:HPChocoOptions = ""
+      $env:HPPath = "${env:ProgramFiles}\Haskell Platform\7.10.3"
+      Invoke-WebRequest -Uri https://haskell.org/platform/download/7.10.3/HaskellPlatform-7.10.3-x86_64-setup.exe -OutFile HaskellPlatform-7.10.3-x86_64-setup.exe
+      .\HaskellPlatform-7.10.3-x86_64-setup.exe /S
+    }
+    # choco install ${env:HPChocoOptions} haskellplatform -version 2014.2.0.0 -y
+    # Haskell Platfrom package doesn't update PATH for the current shell instance
+    $env:Path += ";${env:HPPath}\bin"
+    $env:Path += ";${env:HPPath}\lib\extralibs\bin"
+    $env:Path += ";${env:HPPath}\mingw\bin"
+    $env:Path += ";.\.cabal-sandbox\bin"
+    choco install wixtoolset -version 3.10.1.2213 -y
+    $env:Path += ";${env:ProgramFiles}\WiX Toolset v3.10\bin"
+    $env:Path += ";${env:ProgramFiles(x86)}\WiX Toolset v3.10\bin"
+- cabal sandbox init
+- cabal update
+- cabal install --only-dependencies --enable-tests --enable-benchmarks -fHaskeline -f-Readline
+
+build_script:
+- cabal configure --enable-tests --enable-benchmarks -fHaskeline -f-Readline -v2 # -v2 provides useful information for debugging
+- cabal build
+
+after_build:
+- cmd: |
+   cd windows
+   echo Creating msi...
+   runhaskell build_msi.hs
+   echo Creating zip...
+   cabal install turtle
+   runhaskell build_zip.hs
+   cd ..
+
+test_script:
+- cabal test
+- cabal check
+- cabal sdist
+
+artifacts:
+- path: windows\*.msi
+  name: Windows Installer
+- path: windows\*.zip
+  name: Portable Binary Package
diff --git a/build_bdist_linux.sh b/build_bdist_linux.sh
new file mode 100644
--- /dev/null
+++ b/build_bdist_linux.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+export CABALVER=1.22
+export GHCVER=7.10.2
+
+sudo add-apt-repository -y ppa:hvr/ghc
+sudo apt-get update
+
+sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER
+export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:~/.cabal/bin:$PATH
+sudo apt-get install happy-1.19.4 alex-3.1.3
+export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.4/bin:$PATH
+
+cabal sandbox init
+cabal update
+cabal install -p --only-dependencies -f-Haskeline -f-Readline
+cabal configure -fLinuxStatic -f-Haskeline -f-Readline
+cabal build
+
+VER=`ghc -e ":m + Control.Monad Distribution.Package Distribution.PackageDescription Distribution.PackageDescription.Parse Distribution.Verbosity Data.Version" -e 'putStrLn =<< liftM (showVersion . pkgVersion . package . packageDescription) (readPackageDescription silent "CPL.cabal")'`
+OS=`ghc -e ":m +System.Info" -e "putStrLn os"`
+ARCH=`ghc -e ":m +System.Info" -e "putStrLn arch"`
+
+PKG=CPL-${VER}-${OS}-${ARCH}
+
+rm -r $PKG
+mkdir -p $PKG/bin
+cp dist/build/cpl/cpl $PKG/bin
+cp CHANGELOG.markdown COPYING README.markdown $PKG/
+cp -a samples $PKG
+tar Jcf $PKG.tar.xz $PKG --owner=sakai --group=sakai
diff --git a/src/CDT.hs b/src/CDT.hs
--- a/src/CDT.hs
+++ b/src/CDT.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP, FlexibleContexts #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  CDT
@@ -7,7 +7,7 @@
 -- 
 -- Maintainer  :  masahiro.sakai@gmail.com
 -- Stability   :  provisional
--- Portability :  portable
+-- Portability :  non-portable (CPP, FlexibleContexts)
 --
 -- Categorical Data Type
 --
diff --git a/src/CDTParser.hs b/src/CDTParser.hs
--- a/src/CDTParser.hs
+++ b/src/CDTParser.hs
@@ -57,7 +57,7 @@
        char' ':'
        let f x = x `elemIndex` params
        a <- fe f
-       string' "->"
+       string' "->" <|> string' "→"
        b <- fe f
        return (name, a :-> b)
 
diff --git a/windows/COPYING.rtf b/windows/COPYING.rtf
new file mode 100644
Binary files /dev/null and b/windows/COPYING.rtf differ
diff --git a/windows/CPL.wxs b/windows/CPL.wxs
new file mode 100644
--- /dev/null
+++ b/windows/CPL.wxs
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<?if $(sys.BUILDARCH)=x64 ?>
+  <?define Win64 = "yes" ?>
+  <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
+<?else ?>
+  <?define Win64 = "no" ?>
+  <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
+<?endif ?>
+
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+    <Product Id="AD35BCFF-05F9-4467-B922-B9F76EAB2B1F" Name="Categorical Programming Language" Language="1033" Version="0.0.8.0" Manufacturer="Masahiro Sakai" UpgradeCode="8DBD2D7D-6114-4C47-A307-DD99483568C5">
+        <Package Description="This package is an implementation of &quot;A Categorical Programing Language&quot; (CPL for short) written in Haskell" Comments="Categorical Programming Language" InstallerVersion="200" Compressed="yes" />
+        <Media Id="1" Cabinet="simple.cab" EmbedCab="yes" />
+        <Directory Id="TARGETDIR" Name="SourceDir">
+            <Directory Id="$(var.PlatformProgramFilesFolder)" Name="PFiles">
+                <Directory Id="INSTALLDIR" Name="CPL">
+                    <Directory Id="BINDIR" Name="bin">
+                        <Component Id="MainExecutable" Guid="6E979ACB-D17F-4C9D-8BA0-041FD0D5E987">
+                            <File Id="cplEXE" Name="cpl.exe" Source="..\dist\build\cpl\cpl.exe" />
+                        </Component>
+                    </Directory>
+                    <Directory Id="SAMPLES" Name="samples">
+                        <Component Id="ACK.CPL" DiskId="1" Guid="28C7FD0E-9061-4392-9523-CBF65012F4CD">
+                            <File Id="ACK.CPL" Name="ack.cpl" Source="..\samples\ack.cpl" />
+                        </Component>
+                        <Component Id="ACK_3_4.CPL" DiskId="1" Guid="DC20AC75-DA73-49EA-8960-48B25DA166DB">
+                            <File Id="ACK_3_4.CPL" Name="ack_3_4.cpl" Source="..\samples\ack_3_4.cpl" />
+                        </Component>
+                        <Component Id="AUTOMATA.CDT" DiskId="1" Guid="FFD53683-7D82-4396-8649-0458BA2D695E">
+                            <File Id="AUTOMATA.CDT" Name="automata.cdt" Source="..\samples\automata.cdt" />
+                        </Component>
+                        <Component Id="BENCHMARK.CPL" DiskId="1" Guid="CE930ED5-1D88-4DA9-9BCD-D58C78A9E727">
+                            <File Id="BENCHMARK.CPL" Name="benchmark.cpl" Source="..\samples\benchmark.cpl" />
+                        </Component>
+                        <Component Id="CCC.CDT" DiskId="1" Guid="20974E7A-8454-406F-83B9-83ED7E582B8B">
+                            <File Id="CCC.CDT" Name="ccc.cdt" Source="..\samples\ccc.cdt" />
+                        </Component>
+                        <Component Id="EXAMPLES.CPL" DiskId="1" Guid="A4AF9E9F-E4E5-41A2-8BD4-2A6D271E7334">
+                            <File Id="EXAMPLES.CPL" Name="examples.cpl" Source="..\samples\examples.cpl" />
+                        </Component>
+                        <Component Id="EXAMPLES.TXT" DiskId="1" Guid="7D36629F-D94D-4080-BFC3-1EA5FBD05B33">
+                            <File Id="EXAMPLES.TXT" Name="examples.txt" Source="..\samples\examples.txt" />
+                        </Component>
+                        <Component Id="FUNCTION.CPL" DiskId="1" Guid="2C24BD6E-F9AB-4523-B778-07258DDA11F5">
+                            <File Id="FUNCTION.CPL" Name="function.cpl" Source="..\samples\function.cpl" />
+                        </Component>
+                        <Component Id="MISC.CDT" DiskId="1" Guid="C48F939A-D014-43EF-8631-0C8541A8A7FF">
+                            <File Id="MISC.CDT" Name="misc.cdt" Source="..\samples\misc.cdt" />
+                        </Component>
+                        <Component Id="OBSCURE.CDT" DiskId="1" Guid="FCE812CA-5688-4ABA-BB34-93895E098424">
+                            <File Id="OBSCURE.CDT" Name="obscure.cdt" Source="..\samples\obscure.cdt" />
+                        </Component>
+                        <Component Id="REC.CDT" DiskId="1" Guid="0C90FF11-FA31-44D4-8DD5-7D2B96D10B47">
+                            <File Id="REC.CDT" Name="rec.cdt" Source="..\samples\rec.cdt" />
+                        </Component>
+                    </Directory>
+                    <Component Id="ReadmeFile" Guid="EF38BFDC-5DF3-4F57-8307-75F91183FECF">
+                        <File Id="READMEMD" Name="README.markdown" Source="..\README.markdown" />
+                    </Component>
+                    <Component Id="LicenseFile" Guid="0019EBA5-97D6-44F3-A451-84D8D9D4F89E">
+                        <File Id="COPYING" Name="COPYING" Source="..\COPYING" />
+                    </Component>
+                    <Component Id="ChangeLogFile" Guid="778D69A3-F428-44DD-B9CD-55F976D98F33">
+                        <File Id="CHANGELOGMD" Name="CHANGELOG.markdown" Source="..\CHANGELOG.markdown" />
+                    </Component>
+                </Directory>
+            </Directory>
+        </Directory>
+        <Feature Id="DefaultFeature" Title="Main Feature" Level="1">
+            <ComponentRef Id="MainExecutable" />
+            <ComponentRef Id="ACK.CPL" />
+            <ComponentRef Id="ACK_3_4.CPL" />
+            <ComponentRef Id="AUTOMATA.CDT" />
+            <ComponentRef Id="BENCHMARK.CPL" />
+            <ComponentRef Id="CCC.CDT" />
+            <ComponentRef Id="EXAMPLES.CPL" />
+            <ComponentRef Id="EXAMPLES.TXT" />
+            <ComponentRef Id="FUNCTION.CPL" />
+            <ComponentRef Id="MISC.CDT" />
+            <ComponentRef Id="OBSCURE.CDT" />
+            <ComponentRef Id="REC.CDT" />
+            <ComponentRef Id="ReadmeFile" />
+            <ComponentRef Id="LicenseFile" />
+            <ComponentRef Id="ChangeLogFile" />
+        </Feature>
+        <UI />
+        <UIRef Id="WixUI_InstallDir" />
+        <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
+        <WixVariable Id="WixUILicenseRtf" Value="COPYING.rtf" />
+    </Product>
+</Wix>
diff --git a/windows/build_msi.hs b/windows/build_msi.hs
new file mode 100644
--- /dev/null
+++ b/windows/build_msi.hs
@@ -0,0 +1,39 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+import Control.Exception
+import Control.Monad
+import Data.Version
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Parse
+import Distribution.Verbosity
+import qualified System.Info as SysInfo
+import System.Process
+
+getGitHash :: IO (Maybe String)
+getGitHash =
+  liftM (Just . takeWhile (/='\n')) (readProcess "git" ["rev-parse", "--short", "HEAD"] "")
+  `catch` \(_::SomeException) -> return Nothing
+
+getVersion :: FilePath -> IO Version
+getVersion cabalFile = do
+  pkg <- readPackageDescription silent cabalFile
+  return $ pkgVersion $ package $ packageDescription $ pkg
+
+main :: IO ()
+main = do
+  gitHashMaybe <- getGitHash
+  version <- getVersion "../CPL.cabal"
+  let suffix_githash =
+        case gitHashMaybe of
+          Nothing -> ""
+          Just gitHash -> "_" ++ gitHash
+      msiFileName = "CPL-" ++ showVersion version ++ suffix_githash ++ "-" ++ SysInfo.os ++ "-" ++ SysInfo.arch ++ ".msi"
+      arch =
+        case SysInfo.arch of
+          "x86_64" -> "x64"
+          "i386" -> "x86"
+          s -> s
+  callProcess "candle" $ ["-arch", arch, "CPL.wxs"]
+  callProcess "light" ["-ext", "WixUIExtension", "-out", msiFileName, "CPL.wixobj"]
+  return ()
diff --git a/windows/build_zip.hs b/windows/build_zip.hs
new file mode 100644
--- /dev/null
+++ b/windows/build_zip.hs
@@ -0,0 +1,53 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-}
+import Control.Exception
+import Control.Monad
+import Data.String
+import Data.Version
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Parse
+import Distribution.Verbosity
+import qualified System.Info as SysInfo
+import System.Process
+import Turtle hiding (FilePath)
+
+getGitHash :: IO (Maybe String)
+getGitHash =
+  liftM (Just . takeWhile (/='\n')) (readProcess "git" ["rev-parse", "--short", "HEAD"] "")
+  `catch` \(_::SomeException) -> return Nothing
+
+getVersion :: FilePath -> IO Version
+getVersion cabalFile = do
+  pkg <- readPackageDescription silent cabalFile
+  return $ pkgVersion $ package $ packageDescription $ pkg
+
+main :: IO ()
+main = do
+  gitHashMaybe <- getGitHash
+  version <- getVersion "../CPL.cabal"
+  let suffix_githash =
+        case gitHashMaybe of
+          Nothing -> ""
+          Just gitHash -> "_" ++ gitHash
+      dir :: IsString a => a
+      dir = fromString $ "CPL-" ++ showVersion version ++ suffix_githash ++ "-" ++ SysInfo.os ++ "-" ++ SysInfo.arch
+
+  let binDir = dir </> "bin"
+      samplesDir = dir </> "samples"
+      zipFile :: IsString a => a
+      zipFile = fromString (dir ++ ".zip")
+  testfile zipFile >>= \b -> when b (rm zipFile)
+  testfile dir >>= \b -> when b (rmtree dir)
+  mktree dir
+  mktree binDir
+  mktree samplesDir
+  cp "../dist/build/cpl/cpl.exe" (binDir </> "cpl.exe")
+  sh $ do
+    fpath <- ls "../samples"
+    cp fpath (samplesDir </> filename fpath)
+  cp "../COPYING" (dir </> "COPYING")
+  cp "../README.markdown" (dir </> "README.markdown")
+  cp "../CHANGELOG.markdown" (dir </> "CHANGELOG.markdown")
+  procs "7z" ["a", "-r", zipFile, dir] empty
+  return ()
