fast-combinatorics (empty) → 0.1.0.0
raw patch · 8 files changed
+1111/−0 lines, 8 filesdep +basedep +combinatoricsdep +composition-preludesetup-changed
Dependencies added: base, combinatorics, composition-prelude, criterion, fast-combinatorics, hspec
Files
- LICENSE +11/−0
- README.md +20/−0
- Setup.hs +2/−0
- bench/Bench.hs +18/−0
- cbits/fast-combinatorics.c +959/−0
- fast-combinatorics.cabal +62/−0
- src/Lib.hs +25/−0
- test/Spec.hs +14/−0
+ LICENSE view
@@ -0,0 +1,11 @@+Copyright Vanessa McHale (c) 2017++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,20 @@+# fast-combinatorics++This is a library for fast combinatorics using ATS. You may need to download the +relevant ATS libraries+[here](http://www.ats-lang.org/Downloads.html#Install_of_ATS2_include) if+linking fails.++Currently it is in-progress, being somewhat constrained by the fact that I have+yet to figure out how to share arbitrary-precision types between ATS and Haskell.++# Building++The Haskell library comes with the C bundled, however you may wish to build from+source if you are hacking on the library. To that end, you can install+[stack](http://haskellstack.org/), [patscc](http://www.ats-lang.org/Downloads.html) , and+[pats-filter](https://github.com/Hibou57/PostiATS-Utilities) and build with++```bash+ $ ./shake.hs+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bench/Bench.hs view
@@ -0,0 +1,18 @@+module Main where++import Criterion.Main+import Lib+import qualified Math.Combinatorics.Binomial as MB+import qualified Math.Combinatorics.Factorial as MB++main :: IO ()+main =+ defaultMain [ bgroup "factorial"+ [ bench "factorial" $ nf factorial 12+ , bench "MB.factorial" $ nf factorial 12+ ]+ , bgroup "choose"+ [ bench "choose" $ nf (13 `choose`) 4+ , bench "MB.choose" $ nf (13 `choose`) 4+ ]+ ]
+ cbits/fast-combinatorics.c view
@@ -0,0 +1,959 @@+/*+**+** The C code is generated by [ATS/Postiats-0-3-8]+** The starting compilation time is: 2017-12-30: 10h:46m+**+*/++/*+** include runtime header files+*/+#ifndef _ATS_CCOMP_HEADER_NONE_+#include "pats_ccomp_config.h"+#include "pats_ccomp_basics.h"+#include "pats_ccomp_typedefs.h"+#include "pats_ccomp_instrset.h"+#include "pats_ccomp_memalloc.h"+#ifndef _ATS_CCOMP_EXCEPTION_NONE_+#include "pats_ccomp_memalloca.h"+#include "pats_ccomp_exception.h"+#endif // end of [_ATS_CCOMP_EXCEPTION_NONE_]+#endif /* _ATS_CCOMP_HEADER_NONE_ */+++/*+** include prelude cats files+*/+#ifndef _ATS_CCOMP_PRELUDE_NONE_+//+#include "prelude/CATS/basics.cats"+#include "prelude/CATS/integer.cats"+#include "prelude/CATS/pointer.cats"+#include "prelude/CATS/integer_long.cats"+#include "prelude/CATS/integer_size.cats"+#include "prelude/CATS/integer_short.cats"+#include "prelude/CATS/bool.cats"+#include "prelude/CATS/char.cats"+#include "prelude/CATS/float.cats"+#include "prelude/CATS/integer_ptr.cats"+#include "prelude/CATS/integer_fixed.cats"+#include "prelude/CATS/memory.cats"+#include "prelude/CATS/string.cats"+#include "prelude/CATS/strptr.cats"+//+#include "prelude/CATS/fprintf.cats"+//+#include "prelude/CATS/filebas.cats"+//+#include "prelude/CATS/list.cats"+#include "prelude/CATS/option.cats"+#include "prelude/CATS/array.cats"+#include "prelude/CATS/arrayptr.cats"+#include "prelude/CATS/arrayref.cats"+#include "prelude/CATS/matrix.cats"+#include "prelude/CATS/matrixptr.cats"+//+#endif /* _ATS_CCOMP_PRELUDE_NONE_ */+/*+** for user-supplied prelude+*/+#ifdef _ATS_CCOMP_PRELUDE_USER_+//+#include _ATS_CCOMP_PRELUDE_USER_+//+#endif /* _ATS_CCOMP_PRELUDE_USER_ */+/*+** for user2-supplied prelude+*/+#ifdef _ATS_CCOMP_PRELUDE_USER2_+//+#include _ATS_CCOMP_PRELUDE_USER2_+//+#endif /* _ATS_CCOMP_PRELUDE_USER2_ */++/*+staload-prologues(beg)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/basics.dats: 1636(line=50, offs=1) -- 1675(line=50, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer.dats: 1596(line=49, offs=1) -- 1635(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/pointer.dats: 1533(line=44, offs=1) -- 1572(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer_long.dats: 1602(line=49, offs=1) -- 1641(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer_size.dats: 1597(line=49, offs=1) -- 1636(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer_short.dats: 1603(line=49, offs=1) -- 1642(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/char.dats: 1610(line=48, offs=1) -- 1649(line=48, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/float.dats: 1636(line=50, offs=1) -- 1675(line=50, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/string.dats: 1631(line=50, offs=1) -- 1670(line=50, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/strptr.dats: 1629(line=50, offs=1) -- 1668(line=50, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/strptr.dats: 1691(line=54, offs=1) -- 1738(line=54, offs=48)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer.dats: 1596(line=49, offs=1) -- 1635(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer_ptr.dats: 1601(line=49, offs=1) -- 1640(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer_fixed.dats: 1603(line=49, offs=1) -- 1642(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/memory.dats: 1410(line=38, offs=1) -- 1449(line=39, offs=32)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/filebas.dats: 1613(line=49, offs=1) -- 1652(line=50, offs=32)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/filebas.dats: 1675(line=54, offs=1) -- 1721(line=55, offs=39)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/integer.dats: 1596(line=49, offs=1) -- 1635(line=49, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/filebas.dats: 1744(line=59, offs=1) -- 1789(line=60, offs=38)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/stdio.sats: 1390(line=36, offs=1) -- 1437(line=39, offs=3)+*/++#include \+"libats/libc/CATS/stdio.cats"+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/stdio.sats: 1950(line=69, offs=1) -- 1999(line=71, offs=34)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/sys/types.sats: 1390(line=36, offs=1) -- 1441(line=39, offs=3)+*/++#include \+"libats/libc/CATS/sys/types.cats"+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/filebas.dats: 1871(line=66, offs=1) -- 1918(line=66, offs=48)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/sys/stat.sats: 1390(line=36, offs=1) -- 1440(line=39, offs=3)+*/++#include \+"libats/libc/CATS/sys/stat.cats"+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/sys/stat.sats: 1756(line=58, offs=1) -- 1805(line=60, offs=34)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/sys/types.sats: 1390(line=36, offs=1) -- 1441(line=39, offs=3)+*/++#include \+"libats/libc/CATS/sys/types.cats"+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/filebas.dats: 15552(line=879, offs=1) -- 15589(line=880, offs=30)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/stdio.sats: 1390(line=36, offs=1) -- 1437(line=39, offs=3)+*/++#include \+"libats/libc/CATS/stdio.cats"+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/stdio.sats: 1950(line=69, offs=1) -- 1999(line=71, offs=34)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/libats/libc/SATS/sys/types.sats: 1390(line=36, offs=1) -- 1441(line=39, offs=3)+*/++#include \+"libats/libc/CATS/sys/types.cats"+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/list.dats: 1529(line=44, offs=1) -- 1568(line=45, offs=32)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/list.dats: 1569(line=46, offs=1) -- 1615(line=47, offs=39)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/unsafe.dats: 1532(line=44, offs=1) -- 1566(line=44, offs=35)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/list_vt.dats: 1538(line=44, offs=1) -- 1577(line=45, offs=32)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/list_vt.dats: 1578(line=46, offs=1) -- 1624(line=47, offs=39)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/unsafe.dats: 1532(line=44, offs=1) -- 1566(line=44, offs=35)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/SHARE/list_vt_mergesort.dats: 1546(line=44, offs=1) -- 1585(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/SHARE/list_vt_quicksort.dats: 1546(line=44, offs=1) -- 1585(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/array.dats: 1534(line=44, offs=1) -- 1573(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/array.dats: 1574(line=45, offs=1) -- 1616(line=45, offs=43)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/SHARE/array_bsearch.dats: 1531(line=44, offs=1) -- 1570(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/SHARE/array_quicksort.dats: 1531(line=44, offs=1) -- 1570(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/arrayptr.dats: 1532(line=44, offs=1) -- 1571(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/arrayref.dats: 1532(line=44, offs=1) -- 1571(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/matrix.dats: 1535(line=44, offs=1) -- 1574(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/matrixptr.dats: 1538(line=44, offs=1) -- 1577(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/matrixref.dats: 1538(line=44, offs=1) -- 1577(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/stream.dats: 1523(line=44, offs=1) -- 1562(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/stream_vt.dats: 1523(line=44, offs=1) -- 1562(line=44, offs=40)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/tostring.dats: 1528(line=44, offs=1) -- 1567(line=45, offs=32)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/unsafe.dats: 1532(line=44, offs=1) -- 1566(line=44, offs=35)+*/+/*+/usr/local/lib/ats2-postiats-0.3.8/prelude/DATS/checkast.dats: 1531(line=44, offs=1) -- 1570(line=45, offs=32)+*/+/*+staload-prologues(end)+*/+/*+typedefs-for-tyrecs-and-tysums(beg)+*/+/*+typedefs-for-tyrecs-and-tysums(end)+*/+/*+dynconlst-declaration(beg)+*/+/*+dynconlst-declaration(end)+*/+/*+dyncstlst-declaration(beg)+*/+ATSdyncst_mac(atspre_g0int_mul_int)+ATSdyncst_mac(atspre_g1int_sub_int)+ATSdyncst_mac(atspre_g1int_mul_int)+ATSdyncst_mac(atspre_g1int_add_int)+ATSdyncst_mac(atspre_g0int_div_int)+/*+dyncstlst-declaration(end)+*/+/*+dynvalist-implementation(beg)+*/+/*+dynvalist-implementation(end)+*/+/*+exnconlst-declaration(beg)+*/+#ifndef _ATS_CCOMP_EXCEPTION_NONE_+ATSextern()+atsvoid_t0ype+the_atsexncon_initize+(+ atstype_exnconptr d2c, atstype_string exnmsg+) ;+#endif // end of [_ATS_CCOMP_EXCEPTION_NONE_]+/*+exnconlst-declaration(end)+*/+/*+extypelst-declaration(beg)+*/+/*+extypelst-declaration(end)+*/+/*+assumelst-declaration(beg)+*/+#ifndef _ATS_CCOMP_ASSUME_CHECK_NONE_+#endif // #ifndef(_ATS_CCOMP_ASSUME_CHECK_NONE_)+/*+assumelst-declaration(end)+*/+ATSstatic()+atstkind_t0ype(atstype_int)+fact_0(atstkind_t0ype(atstype_int)) ;++ATSstatic()+atstkind_t0ype(atstype_int)+dfact_3(atstkind_t0ype(atstype_int)) ;++ATSstatic()+atstkind_t0ype(atstype_int)+choose_4(atstkind_t0ype(atstype_int), atstkind_t0ype(atstype_int)) ;++ATSstatic()+atstkind_t0ype(atstype_int)+numerator_loop_5(atstkind_t0ype(atstype_int), atstkind_t0ype(atstype_int)) ;++#if(0)+ATSextern()+atstkind_t0ype(atstype_int)+choose_ats(atstkind_t0ype(atstype_int), atstkind_t0ype(atstype_int)) ;+#endif // end of [QUALIFIED]++#if(0)+ATSextern()+atstkind_t0ype(atstype_int)+double_factorial(atstkind_t0ype(atstype_int)) ;+#endif // end of [QUALIFIED]++#if(0)+ATSextern()+atstkind_t0ype(atstype_int)+factorial_ats(atstkind_t0ype(atstype_int)) ;+#endif // end of [QUALIFIED]++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 70(line=5, offs=5) -- 167(line=8, offs=28)+*/+/*+local: fact_0$0(level=0)+global: fact_0$0(level=0)+local: +global: +*/+ATSstatic()+atstkind_t0ype(atstype_int)+fact_0(atstkind_t0ype(atstype_int) arg0)+{+/* tmpvardeclst(beg) */+ATStmpdec(apy0, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmpret0, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp1, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp2, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+/*+emit_funent_fnxdeclst:+*/+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 70(line=5, offs=5) -- 167(line=8, offs=28)+*/+ATSINSflab(__patsflab_fact_0):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 116(line=6, offs=3) -- 167(line=8, offs=28)+*/+ATScaseof_beg()+/*+** ibranchlst-beg+*/+ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 133(line=7, offs=7) -- 134(line=7, offs=8)+*/+ATSINSlab(__atstmplab0):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 92(line=5, offs=27) -- 93(line=5, offs=28)+*/+ATSifnthen(ATSCKpat_int(arg0, ATSPMVint(0))) { ATSINSgoto(__atstmplab2) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 134(line=7, offs=8) -- 134(line=7, offs=8)+*/+ATSINSlab(__atstmplab1):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 138(line=7, offs=12) -- 139(line=7, offs=13)+*/+ATSINSmove(tmpret0, ATSPMVi0nt(1)) ;+ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 147(line=8, offs=8) -- 147(line=8, offs=8)+*/+ATSINSlab(__atstmplab2):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 157(line=8, offs=18) -- 162(line=8, offs=23)+*/+ATSINSmove(tmp2, atspre_g1int_sub_int(arg0, ATSPMVi0nt(1))) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 152(line=8, offs=13) -- 163(line=8, offs=24)+*/+ATSINSmove(tmp1, fact_0(tmp2)) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 152(line=8, offs=13) -- 167(line=8, offs=28)+*/+ATSINSmove(tmpret0, atspre_g0int_mul_int(tmp1, arg0)) ;++ATSbranch_end()++/*+** ibranchlst-end+*/+ATScaseof_end()++ATSfunbody_end()+ATSreturn(tmpret0) ;+/*+emit_funent_fnxbodylst:+*/+} /* end of [fact_0] */++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 173(line=10, offs=5) -- 285(line=14, offs=29)+*/+/*+local: dfact_3$0(level=0)+global: dfact_3$0(level=0)+local: +global: +*/+ATSstatic()+atstkind_t0ype(atstype_int)+dfact_3(atstkind_t0ype(atstype_int) arg0)+{+/* tmpvardeclst(beg) */+ATStmpdec(apy0, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmpret3, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp4, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp5, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+/*+emit_funent_fnxdeclst:+*/+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 173(line=10, offs=5) -- 285(line=14, offs=29)+*/+ATSINSflab(__patsflab_dfact_3):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 220(line=11, offs=3) -- 285(line=14, offs=29)+*/+ATScaseof_beg()+/*+** ibranchlst-beg+*/+ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 237(line=12, offs=7) -- 238(line=12, offs=8)+*/+ATSINSlab(__atstmplab3):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 196(line=10, offs=28) -- 197(line=10, offs=29)+*/+ATSifnthen(ATSCKpat_int(arg0, ATSPMVint(0))) { ATSINSgoto(__atstmplab5) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 238(line=12, offs=8) -- 238(line=12, offs=8)+*/+ATSINSlab(__atstmplab4):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 242(line=12, offs=12) -- 243(line=12, offs=13)+*/+ATSINSmove(tmpret3, ATSPMVi0nt(1)) ;+ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 250(line=13, offs=7) -- 251(line=13, offs=8)+*/+ATSINSlab(__atstmplab5):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 196(line=10, offs=28) -- 197(line=10, offs=29)+*/+ATSifnthen(ATSCKpat_int(arg0, ATSPMVint(1))) { ATSINSgoto(__atstmplab7) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 251(line=13, offs=8) -- 251(line=13, offs=8)+*/+ATSINSlab(__atstmplab6):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 255(line=13, offs=12) -- 256(line=13, offs=13)+*/+ATSINSmove(tmpret3, ATSPMVi0nt(1)) ;+ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 264(line=14, offs=8) -- 264(line=14, offs=8)+*/+ATSINSlab(__atstmplab7):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 279(line=14, offs=23) -- 284(line=14, offs=28)+*/+ATSINSmove(tmp5, atspre_g1int_sub_int(arg0, ATSPMVi0nt(2))) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 273(line=14, offs=17) -- 285(line=14, offs=29)+*/+ATSINSmove(tmp4, dfact_3(tmp5)) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 269(line=14, offs=13) -- 285(line=14, offs=29)+*/+ATSINSmove(tmpret3, atspre_g0int_mul_int(arg0, tmp4)) ;++ATSbranch_end()++/*+** ibranchlst-end+*/+ATScaseof_end()++ATSfunbody_end()+ATSreturn(tmpret3) ;+/*+emit_funent_fnxbodylst:+*/+} /* end of [dfact_3] */++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 324(line=17, offs=4) -- 680(line=29, offs=6)+*/+/*+local: fact_0$0(level=0)+global: fact_0$0(level=0), choose_4$0(level=0)+local: +global: +*/+ATSstatic()+atstkind_t0ype(atstype_int)+choose_4(atstkind_t0ype(atstype_int) arg0, atstkind_t0ype(atstype_int) arg1)+{+/* tmpvardeclst(beg) */+ATStmpdec(tmpret6, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp13, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp14, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 324(line=17, offs=4) -- 680(line=29, offs=6)+*/+ATSINSflab(__patsflab_choose_4):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 396(line=18, offs=3) -- 680(line=29, offs=6)+*/+/*+letpush(beg)+*/+/*+letpush(end)+*/++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 592(line=25, offs=5) -- 674(line=28, offs=42)+*/+ATScaseof_beg()+/*+** ibranchlst-beg+*/+ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 611(line=26, offs=9) -- 612(line=26, offs=10)+*/+ATSINSlab(__atstmplab13):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 374(line=17, offs=54) -- 375(line=17, offs=55)+*/+ATSifnthen(ATSCKpat_int(arg1, ATSPMVint(0))) { ATSINSgoto(__atstmplab15) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 612(line=26, offs=10) -- 612(line=26, offs=10)+*/+ATSINSlab(__atstmplab14):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 616(line=26, offs=14) -- 617(line=26, offs=15)+*/+ATSINSmove(tmpret6, ATSPMVi0nt(1)) ;+ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 626(line=27, offs=9) -- 627(line=27, offs=10)+*/+ATSINSlab(__atstmplab15):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 374(line=17, offs=54) -- 375(line=17, offs=55)+*/+ATSifnthen(ATSCKpat_int(arg1, ATSPMVint(1))) { ATSINSgoto(__atstmplab17) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 627(line=27, offs=10) -- 627(line=27, offs=10)+*/+ATSINSlab(__atstmplab16):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 631(line=27, offs=14) -- 632(line=27, offs=15)+*/+ATSINSmove(tmpret6, arg0) ;+ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 642(line=28, offs=10) -- 642(line=28, offs=10)+*/+ATSINSlab(__atstmplab17):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 647(line=28, offs=15) -- 663(line=28, offs=31)+*/+ATSINSmove(tmp13, numerator_loop_5(arg0, arg1)) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 667(line=28, offs=35) -- 673(line=28, offs=41)+*/+ATSINSmove(tmp14, fact_0(arg1)) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 647(line=28, offs=15) -- 673(line=28, offs=41)+*/+ATSINSmove(tmpret6, atspre_g0int_div_int(tmp13, tmp14)) ;++ATSbranch_end()++/*+** ibranchlst-end+*/+ATScaseof_end()++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 396(line=18, offs=3) -- 680(line=29, offs=6)+*/+/*+INSletpop()+*/+ATSfunbody_end()+ATSreturn(tmpret6) ;+} /* end of [choose_4] */++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 408(line=19, offs=9) -- 582(line=23, offs=52)+*/+/*+local: numerator_loop_5$0(level=1)+global: numerator_loop_5$0(level=1)+local: n$4734(1)(HSEapp(HSEcst(atstkind_t0ype); HSEs2exp(S2Eextkind(atstype_int))))+global: n$4734(1)(HSEapp(HSEcst(atstkind_t0ype); HSEs2exp(S2Eextkind(atstype_int))))+*/+ATSstatic()+atstkind_t0ype(atstype_int)+numerator_loop_5(atstkind_t0ype(atstype_int) env0, atstkind_t0ype(atstype_int) arg0)+{+/* tmpvardeclst(beg) */+ATStmpdec(tmpret7, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp8, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp9, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp10, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp11, atstkind_t0ype(atstype_int)) ;+ATStmpdec(tmp12, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 408(line=19, offs=9) -- 582(line=23, offs=52)+*/+ATSINSflab(__patsflab_numerator_loop_5):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 476(line=20, offs=7) -- 582(line=23, offs=52)+*/+ATScaseof_beg()+/*+** ibranchlst-beg+*/+ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 497(line=21, offs=11) -- 498(line=21, offs=12)+*/+ATSINSlab(__atstmplab8):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 450(line=19, offs=51) -- 451(line=19, offs=52)+*/+ATSifnthen(ATSCKpat_int(arg0, ATSPMVint(1))) { ATSINSgoto(__atstmplab10) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 498(line=21, offs=12) -- 498(line=21, offs=12)+*/+ATSINSlab(__atstmplab9):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 502(line=21, offs=16) -- 503(line=21, offs=17)+*/+ATSINSmove(tmpret7, env0) ;+ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 514(line=22, offs=11) -- 515(line=22, offs=12)+*/+ATSINSlab(__atstmplab10):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 450(line=19, offs=51) -- 451(line=19, offs=52)+*/+ATSifnthen(ATSCKpat_int(arg0, ATSPMVint(2))) { ATSINSgoto(__atstmplab12) ; } ;+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 515(line=22, offs=12) -- 515(line=22, offs=12)+*/+ATSINSlab(__atstmplab11):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 520(line=22, offs=17) -- 525(line=22, offs=22)+*/+ATSINSmove(tmp8, atspre_g1int_sub_int(env0, ATSPMVi0nt(1))) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 519(line=22, offs=16) -- 530(line=22, offs=27)+*/+ATSINSmove(tmpret7, atspre_g1int_mul_int(tmp8, env0)) ;++ATSbranch_end()++ATSbranch_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 542(line=23, offs=12) -- 542(line=23, offs=12)+*/+ATSINSlab(__atstmplab12):+/*+emit_instr: loc0 = : 0(line=0, offs=0) -- 0(line=0, offs=0)+*/+/*+ibranch-mbody:+*/+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 548(line=23, offs=18) -- 553(line=23, offs=23)+*/+ATSINSmove(tmp10, atspre_g1int_add_int(env0, ATSPMVi0nt(1))) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 548(line=23, offs=18) -- 557(line=23, offs=27)+*/+ATSINSmove(tmp9, atspre_g1int_sub_int(tmp10, arg0)) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 576(line=23, offs=46) -- 581(line=23, offs=51)+*/+ATSINSmove(tmp12, atspre_g1int_sub_int(arg0, ATSPMVi0nt(1))) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 561(line=23, offs=31) -- 582(line=23, offs=52)+*/+ATSINSmove(tmp11, numerator_loop_5(env0, tmp12)) ;++/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 547(line=23, offs=17) -- 582(line=23, offs=52)+*/+ATSINSmove(tmpret7, atspre_g0int_mul_int(tmp9, tmp11)) ;++ATSbranch_end()++/*+** ibranchlst-end+*/+ATScaseof_end()++ATSfunbody_end()+ATSreturn(tmpret7) ;+} /* end of [numerator_loop_5] */++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 793(line=35, offs=22) -- 816(line=36, offs=15)+*/+/*+local: choose_4$0(level=0)+global: fact_0$0(level=0), choose_4$0(level=0), choose_ats$9$0(level=0)+local: +global: +*/+ATSextern()+atstkind_t0ype(atstype_int)+choose_ats(atstkind_t0ype(atstype_int) arg0, atstkind_t0ype(atstype_int) arg1)+{+/* tmpvardeclst(beg) */+ATStmpdec(tmpret15, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 782(line=35, offs=11) -- 816(line=36, offs=15)+*/+ATSINSflab(__patsflab_choose_ats):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 804(line=36, offs=3) -- 816(line=36, offs=15)+*/+ATSINSmove(tmpret15, choose_4(arg0, arg1)) ;++ATSfunbody_end()+ATSreturn(tmpret15) ;+} /* end of [choose_ats] */++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 911(line=42, offs=28) -- 926(line=43, offs=10)+*/+/*+local: dfact_3$0(level=0)+global: dfact_3$0(level=0), double_factorial$10$0(level=0)+local: +global: +*/+ATSextern()+atstkind_t0ype(atstype_int)+double_factorial(atstkind_t0ype(atstype_int) arg0)+{+/* tmpvardeclst(beg) */+ATStmpdec(tmpret16, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 894(line=42, offs=11) -- 927(line=43, offs=11)+*/+ATSINSflab(__patsflab_double_factorial):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 919(line=43, offs=3) -- 926(line=43, offs=10)+*/+ATSINSmove(tmpret16, dfact_3(arg0)) ;++ATSfunbody_end()+ATSreturn(tmpret16) ;+} /* end of [double_factorial] */++/*+/home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 1016(line=49, offs=25) -- 1030(line=50, offs=9)+*/+/*+local: fact_0$0(level=0)+global: fact_0$0(level=0), factorial_ats$11$0(level=0)+local: +global: +*/+ATSextern()+atstkind_t0ype(atstype_int)+factorial_ats(atstkind_t0ype(atstype_int) arg0)+{+/* tmpvardeclst(beg) */+ATStmpdec(tmpret17, atstkind_t0ype(atstype_int)) ;+/* tmpvardeclst(end) */+ATSfunbody_beg()+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 1002(line=49, offs=11) -- 1031(line=50, offs=10)+*/+ATSINSflab(__patsflab_factorial_ats):+/*+emit_instr: loc0 = /home/vanessa/programming/haskell/current/fast-combinatorics/ats-src/fast-combinatorics.dats: 1024(line=50, offs=3) -- 1030(line=50, offs=9)+*/+ATSINSmove(tmpret17, fact_0(arg0)) ;++ATSfunbody_end()+ATSreturn(tmpret17) ;+} /* end of [factorial_ats] */++/*+** for initialization(dynloading)+*/+ATSdynloadflag_minit(_057_home_057_vanessa_057_programming_057_haskell_057_current_057_fast_055_combinatorics_057_ats_055_src_057_fast_055_combinatorics_056_dats__dynloadflag) ;+ATSextern()+atsvoid_t0ype+_057_home_057_vanessa_057_programming_057_haskell_057_current_057_fast_055_combinatorics_057_ats_055_src_057_fast_055_combinatorics_056_dats__dynload()+{+ATSfunbody_beg()+ATSdynload(/*void*/)+ATSdynloadflag_sta(+_057_home_057_vanessa_057_programming_057_haskell_057_current_057_fast_055_combinatorics_057_ats_055_src_057_fast_055_combinatorics_056_dats__dynloadflag+) ;+ATSif(+ATSCKiseqz(+_057_home_057_vanessa_057_programming_057_haskell_057_current_057_fast_055_combinatorics_057_ats_055_src_057_fast_055_combinatorics_056_dats__dynloadflag+)+) ATSthen() {+ATSdynloadset(_057_home_057_vanessa_057_programming_057_haskell_057_current_057_fast_055_combinatorics_057_ats_055_src_057_fast_055_combinatorics_056_dats__dynloadflag) ;+/*+dynexnlst-initize(beg)+*/+/*+dynexnlst-initize(end)+*/+} /* ATSendif */+ATSfunbody_end()+ATSreturn_void(tmpret_void) ;+} /* end of [*_dynload] */++/* ****** ****** */++/* end-of-compilation-unit */
+ fast-combinatorics.cabal view
@@ -0,0 +1,62 @@+name: fast-combinatorics+version: 0.1.0.0+synopsis: Fast combinatorics.+description: Fast combinatorics code with a high level of safety guaranteed by writing it in ATS.+homepage: https://github.com//fast-combinatorics#readme+license: BSD3+license-file: LICENSE+author: Vanessa McHale+maintainer: vamchale@gmail.com+copyright: Copyright: (c) 2017 Vanessa McHale+category: Numerics+build-type: Simple+extra-source-files: cbits/fast-combinatorics.c+extra-doc-files: README.md+cabal-version: >=1.18++Flag development {+ Description: Enable `-Werror`+ manual: True+ default: False+}++library+ c-sources: cbits/fast-combinatorics.c+ hs-source-dirs: src+ exposed-modules: Lib+ build-depends: base >= 4.7 && < 5+ , composition-prelude+ default-language: Haskell2010+ if flag(development)+ ghc-options: -Werror+ ghc-options: -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat++test-suite fast-combinatorics-test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ build-depends: base+ , fast-combinatorics+ , hspec+ , combinatorics+ if flag(development)+ ghc-options: -Werror+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat+ default-language: Haskell2010++benchmark fast-combinatorics-bench+ type: exitcode-stdio-1.0+ hs-source-dirs: bench+ main-is: Bench.hs+ build-depends: base+ , fast-combinatorics+ , criterion+ , combinatorics+ if flag(development)+ ghc-options: -Werror+ ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat -optc-mtune=native -optc-flto+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com//fast-combinatorics
+ src/Lib.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE ForeignFunctionInterface #-}++module Lib+ ( factorial+ , choose+ , doubleFactorial+ ) where++import Control.Composition+import Foreign.C++foreign import ccall unsafe factorial_ats :: CInt -> CInt+foreign import ccall unsafe choose_ats :: CInt -> CInt -> CInt+foreign import ccall unsafe double_factorial :: CInt -> CInt++{-@ choose :: { n : Nat | n >= 0 } -> { k : Nat | k >= 0 && k <= n } -> Int @-}+choose :: Int -> Int -> Int+choose = fromIntegral .* on choose_ats fromIntegral++doubleFactorial :: Int -> Int+doubleFactorial = fromIntegral . double_factorial . fromIntegral++{-@ factorial :: { n : Nat | n <= 0 } -> Int @-}+factorial :: Int -> Int+factorial = fromIntegral . factorial_ats . fromIntegral
+ test/Spec.hs view
@@ -0,0 +1,14 @@+import Lib+import Test.Hspec+import Test.Hspec.QuickCheck+import qualified Math.Combinatorics.Binomial as MB+import qualified Math.Combinatorics.Factorial as MB++main :: IO ()+main = hspec $ do+ parallel $ describe "factorial" $+ prop "should agree with the pure Haskell function" $+ \x -> x < 1 || x > 12 || factorial x == MB.factorial (fromIntegral x)+ parallel $ describe "choose" $+ prop "should agree with the pure Haskell function" $+ \x y -> x < 0 || y < 0 || x > 13 || y > 12 || (x `choose` y) == (x `MB.choose` y)