module Math.OEIS
(
getSequenceByID, lookupSequenceByID
, extendSequence, lookupSequence
, getSequenceByID_IO, lookupSequenceByID_IO
, extendSequence_IO, lookupSequence_IO
, searchSequence_IO, lookupOEIS
, searchSequences_IO, lookupSequences_IO
, SequenceData
, Language(..), Keyword(..)
, OEISSequence(..)
) where
import Control.Applicative ((<$>))
import Prelude
import Data.Char (isDigit, isSpace)
import Data.List (isPrefixOf, tails, find)
import Data.Maybe (listToMaybe, fromMaybe)
import Network.URI (escapeURIString, isAllowedInURI)
import System.IO.Unsafe (unsafePerformIO)
import Math.OEIS.Internal
import Math.OEIS.Types
lookupOEIS :: String -> IO [String]
lookupOEIS :: String -> IO [String]
lookupOEIS String
a = do
let a' :: String
a' = String -> String
commas (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
a
Maybe OEISSequence
x <- String -> IO (Maybe OEISSequence)
searchSequence_IO String
a'
case Maybe OEISSequence
x of
Maybe OEISSequence
Nothing -> [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [String
"Sequence not found."]
Just OEISSequence
s -> [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [OEISSequence -> String
description OEISSequence
s, SequenceData -> String
forall a. Show a => a -> String
show (SequenceData -> String) -> SequenceData -> String
forall a b. (a -> b) -> a -> b
$ OEISSequence -> SequenceData
sequenceData OEISSequence
s]
where commas :: String -> String
commas [] = []
commas (Char
x:Char
' ':String
xs) | Char -> Bool
isDigit Char
x = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: Char
',' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
commas String
xs
commas (Char
x:String
xs) = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
commas String
xs
searchSequence_IO :: String -> IO (Maybe OEISSequence)
searchSequence_IO :: String -> IO (Maybe OEISSequence)
searchSequence_IO String
x = [OEISSequence] -> Maybe OEISSequence
forall a. [a] -> Maybe a
listToMaybe ([OEISSequence] -> Maybe OEISSequence)
-> IO [OEISSequence] -> IO (Maybe OEISSequence)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO [OEISSequence]
searchSequences_IO String
x
searchSequences_IO :: String -> IO [OEISSequence]
searchSequences_IO :: String -> IO [OEISSequence]
searchSequences_IO String
x = (String -> String) -> String -> IO [OEISSequence]
forall a. (a -> String) -> a -> IO [OEISSequence]
getOEIS (String
baseSearchURI String -> String -> String
forall a. [a] -> [a] -> [a]
++) ((Char -> Bool) -> String -> String
escapeURIString Char -> Bool
isAllowedInURI String
x)
getSequenceByID :: String -> Maybe SequenceData
getSequenceByID :: String -> Maybe SequenceData
getSequenceByID = IO (Maybe SequenceData) -> Maybe SequenceData
forall a. IO a -> a
unsafePerformIO (IO (Maybe SequenceData) -> Maybe SequenceData)
-> (String -> IO (Maybe SequenceData))
-> String
-> Maybe SequenceData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO (Maybe SequenceData)
getSequenceByID_IO
getSequenceByID_IO :: String -> IO (Maybe SequenceData)
getSequenceByID_IO :: String -> IO (Maybe SequenceData)
getSequenceByID_IO String
x = (Maybe OEISSequence -> Maybe SequenceData)
-> IO (Maybe OEISSequence) -> IO (Maybe SequenceData)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((OEISSequence -> SequenceData)
-> Maybe OEISSequence -> Maybe SequenceData
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OEISSequence -> SequenceData
sequenceData) (String -> IO (Maybe OEISSequence)
lookupSequenceByID_IO String
x)
lookupSequenceByID :: String -> Maybe OEISSequence
lookupSequenceByID :: String -> Maybe OEISSequence
lookupSequenceByID = IO (Maybe OEISSequence) -> Maybe OEISSequence
forall a. IO a -> a
unsafePerformIO (IO (Maybe OEISSequence) -> Maybe OEISSequence)
-> (String -> IO (Maybe OEISSequence))
-> String
-> Maybe OEISSequence
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO (Maybe OEISSequence)
lookupSequenceByID_IO
lookupSequenceByID_IO :: String -> IO (Maybe OEISSequence)
lookupSequenceByID_IO :: String -> IO (Maybe OEISSequence)
lookupSequenceByID_IO String
x = [OEISSequence] -> Maybe OEISSequence
forall a. [a] -> Maybe a
listToMaybe ([OEISSequence] -> Maybe OEISSequence)
-> IO [OEISSequence] -> IO (Maybe OEISSequence)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> String) -> String -> IO [OEISSequence]
forall a. (a -> String) -> a -> IO [OEISSequence]
getOEIS String -> String
idSearchURI String
x
extendSequence :: SequenceData -> SequenceData
extendSequence :: SequenceData -> SequenceData
extendSequence = IO SequenceData -> SequenceData
forall a. IO a -> a
unsafePerformIO (IO SequenceData -> SequenceData)
-> (SequenceData -> IO SequenceData)
-> SequenceData
-> SequenceData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SequenceData -> IO SequenceData
extendSequence_IO
extendSequence_IO :: [Integer] -> IO [Integer]
extendSequence_IO :: SequenceData -> IO SequenceData
extendSequence_IO [] = SequenceData -> IO SequenceData
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
extendSequence_IO SequenceData
xs = do
Maybe OEISSequence
oeis <- SequenceData -> IO (Maybe OEISSequence)
lookupSequence_IO SequenceData
xs
SequenceData -> IO SequenceData
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (SequenceData -> IO SequenceData)
-> SequenceData -> IO SequenceData
forall a b. (a -> b) -> a -> b
$ case Maybe OEISSequence
oeis of
Maybe OEISSequence
Nothing -> SequenceData
xs
Just OEISSequence
s -> SequenceData -> SequenceData -> SequenceData
extend SequenceData
xs (OEISSequence -> SequenceData
sequenceData OEISSequence
s)
extend :: SequenceData -> SequenceData -> SequenceData
extend :: SequenceData -> SequenceData -> SequenceData
extend SequenceData
xs SequenceData
ext = SequenceData -> Maybe SequenceData -> SequenceData
forall a. a -> Maybe a -> a
fromMaybe SequenceData
xs (Maybe SequenceData -> SequenceData)
-> ([SequenceData] -> Maybe SequenceData)
-> [SequenceData]
-> SequenceData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SequenceData -> Bool) -> [SequenceData] -> Maybe SequenceData
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (SequenceData
xs SequenceData -> SequenceData -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`) ([SequenceData] -> SequenceData) -> [SequenceData] -> SequenceData
forall a b. (a -> b) -> a -> b
$ SequenceData -> [SequenceData]
forall a. [a] -> [[a]]
tails SequenceData
ext
lookupSequence :: SequenceData -> Maybe OEISSequence
lookupSequence :: SequenceData -> Maybe OEISSequence
lookupSequence = IO (Maybe OEISSequence) -> Maybe OEISSequence
forall a. IO a -> a
unsafePerformIO (IO (Maybe OEISSequence) -> Maybe OEISSequence)
-> (SequenceData -> IO (Maybe OEISSequence))
-> SequenceData
-> Maybe OEISSequence
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SequenceData -> IO (Maybe OEISSequence)
lookupSequence_IO
lookupSequence_IO :: SequenceData -> IO (Maybe OEISSequence)
lookupSequence_IO :: SequenceData -> IO (Maybe OEISSequence)
lookupSequence_IO SequenceData
x = [OEISSequence] -> Maybe OEISSequence
forall a. [a] -> Maybe a
listToMaybe ([OEISSequence] -> Maybe OEISSequence)
-> IO [OEISSequence] -> IO (Maybe OEISSequence)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SequenceData -> IO [OEISSequence]
lookupSequences_IO SequenceData
x
lookupSequences_IO :: SequenceData -> IO [OEISSequence]
lookupSequences_IO :: SequenceData -> IO [OEISSequence]
lookupSequences_IO = (SequenceData -> String) -> SequenceData -> IO [OEISSequence]
forall a. (a -> String) -> a -> IO [OEISSequence]
getOEIS SequenceData -> String
seqSearchURI
{-# ANN module "HLint: ignore Use camelCase" #-}