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
data Prime int = Prime { _value :: !int, _index :: !Int } deriving Show
getValue :: Prime int -> int
getValue = _value
getIndex :: Prime int -> Int
getIndex = _index
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)
primeIndex :: Integral n => n -> Maybe Int
primeIndex x | isPrime x = elemIndex x primes
| otherwise = Nothing
getPrime :: Integral int => Int -> Prime int
getPrime n = Prime (primes !! n) n
maybePrime :: (Integral int) => int -> Maybe (Prime int)
maybePrime x = Prime x <$> primeIndex x
indexedPrimes :: Integral int => [Prime int]
indexedPrimes = getPrime <$> [0,1..]