{-# OPTIONS_GHC -funbox-strict-fields #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE DeriveGeneric #-} module Data.Numbers.Primes.Type ( Prime , getValue , getIndex , deconstruct , primeIndex , getPrime , maybePrime , indexedPrimes ) where import Data.List (elemIndex) import Data.Numbers.Primes import GHC.Generics import Control.DeepSeq -- | An abstract type for primes. -- -- It will only ever hold a valid prime, along with its zero-based index. data Prime int = Prime { _value :: !int, _index :: !Int } deriving Show -- | Given a Prime, give back its value. getValue :: Prime int -> int getValue = _value -- | Given a Prime, give back its index. getIndex :: Prime int -> Int getIndex = _index -- | Given a Prime, give back its value and index as a tuple. deconstruct :: Prime int -> (int, Int) deconstruct p = (_value p, _index p) instance Integral int => Enum (Prime int) where toEnum = getPrime fromEnum = getIndex instance Eq (Prime int) where x == y = getIndex x == getIndex y instance Ord (Prime int) where x `compare` y = getIndex x `compare` getIndex y deriving instance Generic (Prime a) instance NFData a => NFData (Prime a) -- | If a given number is prime, give back its index. primeIndex :: Integral n => n -> Maybe Int primeIndex x | isPrime x = elemIndex x primes | otherwise = Nothing -- | Give n-th prime. getPrime :: Integral int => Int -> Prime int getPrime n = Prime (primes !! n) n -- | If a given number is prime, give it back wrapped as such. maybePrime :: (Integral int) => int -> Maybe (Prime int) maybePrime x = Prime x <$> primeIndex x -- | List of indexed primes. indexedPrimes :: Integral int => [Prime int] indexedPrimes = getPrime <$> [0,1..]