oeis 0.3.1 → 0.3.2
raw patch · 9 files changed
+121/−109 lines, 9 filesdep +HUnitdep +oeisdep +test-frameworkdep ~HTTPdep ~basesetup-changed
Dependencies added: HUnit, oeis, test-framework, test-framework-hunit
Dependency ranges changed: HTTP, base
Files
- LICENSE +1/−1
- README +0/−2
- README.md +4/−0
- Setup.hs +3/−10
- Test.hs +36/−0
- example/Catalan.hs +0/−26
- oeis.cabal +43/−15
- src/Math/OEIS.hs +34/−37
- src/test.hs +0/−18
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) Brent Yorgey 2007+Copyright (c) Brent Yorgey 2007, Brian Lewis 2013 All rights reserved.
− README
@@ -1,2 +0,0 @@-Math.OEIS is a library module for interfacing with the Online Encyclopedia of-Integer Sequences (http://oeis.org/).
+ README.md view
@@ -0,0 +1,4 @@+`Math.OEIS` is a library module for interfacing with the+[Online Encyclopedia of Integer Sequences][1].++[1]: http://oeis.org/
Setup.hs view
@@ -1,13 +1,6 @@-module Main where--import System.Process (system)+module Main (main) where -import Distribution.Simple (defaultMainWithHooks, simpleUserHooks, runTests)+import Distribution.Simple (defaultMain) main :: IO ()-main =- defaultMainWithHooks $ simpleUserHooks { runTests = runTests' }- where- runTests' _ _ _ _ = do- system "runhaskell -Wall -i./src src/test.hs"- return ()+main = defaultMain
+ Test.hs view
@@ -0,0 +1,36 @@+import Test.HUnit ((@?=))++import qualified Test.Framework as TF+import qualified Test.Framework.Providers.HUnit as TF+import qualified Test.HUnit as HU++import qualified Math.OEIS as OEIS++--------------------------------------------------------------------------------++main :: IO ()+main =+ TF.defaultMain tests++--------------------------------------------------------------------------------++tests :: [TF.Test]+tests =+ [ TF.testGroup "main"+ [ TF.testCase "lookupSequenceByID" test_lookupSequenceByID+ ]+ ]++--------------------------------------------------------------------------------++test_lookupSequenceByID :: IO ()+test_lookupSequenceByID = do+ let m = OEIS.lookupSequenceByID "A000040"+ case m of+ Nothing -> HU.assertFailure ""+ Just r -> do+ OEIS.catalogNums r @?= ["A000040", "M0652", "N0241"]+ OEIS.description r @?= "The prime numbers."+ OEIS.keywords r @?= [OEIS.Core, OEIS.Nonn, OEIS.Nice, OEIS.Easy, OEIS.Changed]++{-# ANN module "HLint: ignore Use camelCase" #-}
− example/Catalan.hs
@@ -1,26 +0,0 @@-import Math.OEIS-import Data.List (genericLength)---- data-less binary trees.-data BTree = Empty | Fork BTree BTree deriving Show---- A list of all the binary trees with exactly n nodes.-listTrees :: Int -> [BTree]-listTrees 0 = [Empty]-listTrees n = [Fork left right | - k <- [0..n-1],- left <- listTrees k,- right <- listTrees (n-1-k) ]---- HORRIBLY INEFFICIENT!!-countTrees :: Int -> Integer-countTrees = genericLength . listTrees---- This is about the best we can do.-smallTreeCounts = map countTrees [0..10]---- so... cheat! Extend the sequence via the OEIS.-treeCounts = extendSequence smallTreeCounts--countTrees' :: Int -> Integer-countTrees' n = treeCounts !! n
oeis.cabal view
@@ -1,39 +1,67 @@ name: oeis-version: 0.3.1-stability: experimental+version: 0.3.2 category: Math-synopsis: Interface to the Online Encyclopedia of Integer Sequences-description: Interface to the Online Encyclopedia of Integer Sequences. See <http://oeis.org/>.+stability: experimental+ author: Brent Yorgey maintainer: Brian Lewis <brian@lorf.org>+ license: BSD3 license-file: LICENSE -cabal-version: >= 1.6+synopsis: Interface to the Online Encyclopedia of Integer Sequences (OEIS)+description:+ Interface to the Online Encyclopedia of Integer Sequences (OEIS). See+ <http://oeis.org/>.++cabal-version: >= 1.10 build-type: Custom -data-files:- README- example/Catalan.hs+-------------------------------------------------------------------------------- extra-source-files:- src/test.hs+ README.md +--------------------------------------------------------------------------------+ library- hs-source-dirs:- src+ default-language: Haskell2010 + ghc-options: -Wall -O2+ if impl(ghc >= 6.8)+ ghc-options: -fwarn-tabs+ exposed-modules: Math.OEIS + hs-source-dirs:+ src+ build-depends:- base == 3.* || == 4.*,- network == 2.*,- HTTP >= 4000.0.2 || == 4000.1.*+ HTTP == 4000.*,+ base == 4.*,+ network == 2.* - ghc-options: -Wall+--------------------------------------------------------------------------------++test-suite main+ default-language: Haskell2010++ ghc-options: -Wall -O2 if impl(ghc >= 6.8) ghc-options: -fwarn-tabs++ type: exitcode-stdio-1.0+ main-is: Test.hs++ build-depends:+ HUnit == 1.*,+ base == 4.*,+ oeis == 0.*,+ test-framework == 0.*,+ test-framework-hunit == 0.*++-------------------------------------------------------------------------------- source-repository head type: git
src/Math/OEIS.hs view
@@ -1,36 +1,34 @@--- | A Haskell interface to the Online Encyclopedia of Integer Sequences--- (OEIS), <http://oeis.org/>.+-- | Interface to the Online Encyclopedia of Integer Sequences (OEIS). See+-- <http://oeis.org/>. module Math.OEIS- (- -- * Example usage+ ( -- * Example usage -- $sample -- * Lookup functions- getSequenceByID, lookupSequenceByID,- extendSequence, lookupSequence,+ getSequenceByID, lookupSequenceByID,+ extendSequence, lookupSequence, getSequenceByID_IO, lookupSequenceByID_IO,- extendSequence_IO, lookupSequence_IO,- searchSequence_IO, lookupOEIS,+ extendSequence_IO, lookupSequence_IO,+ searchSequence_IO, lookupOEIS, -- * Data structures SequenceData, Language(..), Keyword(..), OEISSequence(..)- ) where -import Control.Arrow (second, (***))-import Data.Char (isDigit, isSpace, toUpper, toLower)-import Data.List (intercalate, isPrefixOf, tails, foldl')-import Data.Maybe (listToMaybe, fromMaybe)-import Network.HTTP -- (simpleHTTP, rspBody, rspCode, rqBody, rqHeaders, rqMethod, rqURI, Request(..), GET)-import Network.URI (escapeURIString, isAllowedInURI, parseURI, URI)+import Control.Arrow (second, (***))+import Data.Char (isDigit, isSpace, toUpper, toLower)+import Data.List (intercalate, isPrefixOf, tails, foldl')+import Data.Maybe (listToMaybe, fromMaybe)+import Network.HTTP (simpleHTTP, rspBody, rspCode, rqBody, rqHeaders, rqMethod, rqURI, Request(..), RequestMethod(GET))+import Network.URI (escapeURIString, isAllowedInURI, parseURI, URI) import System.IO.Unsafe (unsafePerformIO) type SequenceData = [Integer] --- | Interpret a string as a OEIS request, and return the results as Strings+-- | Interpret a string as a OEIS request, and return the results as Strings. lookupOEIS :: String -> IO [String] lookupOEIS a = do let a' = commas . reverse . dropWhile isSpace . reverse . dropWhile isSpace $ a@@ -42,22 +40,20 @@ commas (x:' ':xs) | isDigit x = x : ',' : commas xs commas (x:xs) = x : commas xs ---- | Look up a sequence in the OEIS using its search function+-- | Look up a sequence in the OEIS using its search function. searchSequence_IO :: String -> IO (Maybe OEISSequence) searchSequence_IO x = getOEIS (baseSearchURI ++) (escapeURIString isAllowedInURI x) --- | Look up a sequence in the OEIS by its catalog number. Generally this--- would be its A-number, but--- M-numbers (from the /Encyclopedia of Integer Sequences/) and--- N-numbers (from the /Handbook of Integer Sequences/) can be used as well.+-- | Look up a sequence in the OEIS by its catalog number. Generally this would+-- be its A-number, but M-numbers (from the /Encyclopedia of Integer+-- Sequences/) and N-numbers (from the /Handbook of Integer Sequences/) can be+-- used as well. -- -- Note that the result is not in the 'IO' monad, even though the -- implementation requires looking up information via the Internet. There are -- no side effects to speak of, and from a practical point of view the function -- is referentially transparent (OEIS A-numbers could change in theory, but--- it's extremely unlikely). If you're a nitpicky purist, feel free to use the--- provided 'getSequenceByID_IO' instead.+-- it's extremely unlikely). -- -- Examples: --@@ -305,7 +301,7 @@ parseItem s = (c, str) where ( '%':c:_ , rest) = splitWord s (_, str ) = if c == 'I' then ("", rest)- else splitWord rest+ else splitWord rest combineConts :: [String] -> [String] combineConts (s@('%':_:_) : ss) =@@ -326,9 +322,9 @@ {- $sample -Suppose we are interested in answering the question, \"how many-distinct binary trees are there with exactly 20 nodes?\" Some naive-code to answer this question might be as follows:+Suppose we are interested in answering the question, \"how many distinct binary+trees are there with exactly 20 nodes?\" Some naive code to answer this+question might be as follows: > import Data.List (genericLength) >@@ -363,7 +359,7 @@ *** Exception: stack overflow @ -There's really no way we can evaluate @countTrees 20@. The solution? Cheat!+There's really no way we can evaluate @countTrees 20@. The solution? Cheat! > import Math.OEIS >@@ -379,18 +375,17 @@ > *Main> treeCounts !! 20 > 6564120420 -Sweet. Of course, to have any sort of confidence in our answer, more-research is required! Let's see what combinatorial goodness we have-stumbled across.+Sweet. Of course, to have any sort of confidence in our answer, more research+is required! Let's see what combinatorial goodness we have stumbled across. @ *Main> description \`fmap\` lookupSequence smallTreeCounts Just \"Catalan numbers: C(n) = binomial(2n,n)\/(n+1) = (2n)!\/(n!(n+1)!). Also called Segner numbers.\" @ -Catalan numbers, interesting. And a nice formula we could use to code-up a /real/ solution! Hmm, where can we read more about these-so-called \'Catalan numbers\'?+Catalan numbers, interesting. And a nice formula we could use to code up a+/real/ solution! Hmm, where can we read more about these so-called \'Catalan+numbers\'? @ *Main> (head . references) \`fmap\` lookupSequence smallTreeCounts@@ -399,6 +394,8 @@ Just [\"N. J. A. Sloane, \<a href=\\\"http:\/\/www.research.att.com\/~njas\/sequences\/b000108.txt\\\"\>The first 200 Catalan numbers\<\/a\>\"] @ -And so on. Reams of collected mathematical knowledge at your-fingertips! You must promise only to use this power for Good.+And so on. Reams of collected mathematical knowledge at your fingertips! You+must promise only to use this power for Good. -}++{-# ANN module "HLint: ignore Use camelCase" #-}
− src/test.hs
@@ -1,18 +0,0 @@-module Main where--import qualified Math.OEIS as OEIS--main :: IO ()-main =- case OEIS.lookupSequenceByID "A000040" of- Just s -> do- print $ OEIS.catalogNums s- print $ OEIS.description s- print $ OEIS.keywords s-- let sd = OEIS.sequenceData s- if sd == OEIS.extendSequence (take 10 sd)- then putStrLn "lookupSequence ok"- else putStrLn "lookupSequence failed"-- Nothing -> print "unable to look up A000040"