Skip to content

Instantly share code, notes, and snippets.

@MichaelXavier
Created March 10, 2017 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MichaelXavier/577f8d32323da707acb3d488b1a41ee2 to your computer and use it in GitHub Desktop.
Save MichaelXavier/577f8d32323da707acb3d488b1a41ee2 to your computer and use it in GitHub Desktop.
Customizable per page smart constructor using type-level naturals
module PerPage
( PerPage -- don't export the constructor, only constructable via smart constructor prism
, perPage
) where
import qualified Control.Lens as L
import qualified GHC.TypeLits as TL
import Data.Proxy (Proxy(..))
-- Represents a per page parameter you may accept on a web server, API, etc for pagination.
newtype PerPage (max :: TL.Nat) = PerPage Int deriving (Show, Eq, Ord)
instance (TL.KnownNat max) => Bounded (PerPage max) where
minBound = PerPage 1
maxBound = PerPage (fromInteger (TL.natVal (Proxy :: Proxy max)))
perPage :: forall max. (TL.KnownNat max) => L.Prism' Int (PerPage max)
perPage = L.prism' toI fromI
where
toI (PerPage i) = i
fromI i = let pp = PerPage i
in if pp >= minBound && pp <= maxBound
then Just pp
else Nothing
-- examples
type UsersPerPage = PerPage 50
parseUsersPerPage :: Int -> Maybe UsersPerPage
parseUsersPerPage = L.preview perPage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment