Created
March 10, 2017 19:01
-
-
Save MichaelXavier/577f8d32323da707acb3d488b1a41ee2 to your computer and use it in GitHub Desktop.
Customizable per page smart constructor using type-level naturals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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