Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4548750
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 21, 20262026-05-21T16:15:51+00:00 2026-05-21T16:15:51+00:00

Thanks to newtype and the GeneralizedNewtypeDeriving extension, one can define distinct lightweight types with

  • 0

Thanks to newtype and the GeneralizedNewtypeDeriving extension, one can define distinct lightweight types with little effort:

newtype PersonId = PersonId Int deriving (Eq, Ord, Show, NFData, ...)
newtype GroupId  = GroupId Int deriving (Eq, Ord, Show, NFData, ...)

which allows the type-system to make sure a PersonId is not used by accident where a GroupId was expected, but still inherit selected typeclass instances from Int.

Now one could simply define PersonIdSet and GroupIdSet as

import Data.Set (Set)
import qualified Data.Set as Set

type PersonIdSet = Set PersonId
type GroupIdSet  = Set GroupId

noGroups :: GroupIdSet
noGroups = Set.empty

-- should not type-check
foo = PersonId 123 `Set.member` noGroups

-- should type-check
bar = GroupId 123 `Set.member` noGroups

which is type safe, since map is parametrized by the key-type, and also, the Set.member operation is polymorphic so I don’t need to define per-id-type variants such as personIdSetMember and groupIdSetMember (and all other set-operations I might want to use)

…but how can I use the more efficient IntSets instead for PersonIdSet and GroupIdSet respectively in a similiar way to the example above? Is there a simple way w/o having to wrap/replicate the whole Data.IntSet API as a typeclass?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-21T16:15:52+00:00Added an answer on May 21, 2026 at 4:15 pm

    I think you have to wrap IntSet as you said. However, rather than defining each ID type separately, you can introduce a phantom type to create a family of IDs and IDSets that are compatible with one another:

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    
    import qualified Data.IntSet as IntSet
    import Data.IntSet (IntSet)
    
    newtype ID a = ID { unID :: Int }
                  deriving ( Eq, Ord, Show, Num )
    
    newtype IDSet a = IDSet { unIDSet :: IntSet }
                  deriving ( Eq, Ord, Show )
    
    null :: IDSet a -> Bool
    null = IntSet.null . unIDSet
    
    member :: ID a -> IDSet a -> Bool
    member i = IntSet.member (unID i) . unIDSet
    
    empty :: IDSet a
    empty = IDSet $ IntSet.empty
    
    singleton :: ID a -> IDSet a
    singleton = IDSet . IntSet.singleton . unID
    
    insert :: ID a -> IDSet a -> IDSet a
    insert i = IDSet . IntSet.insert (unID i) . unIDSet
    
    delete :: ID a -> IDSet a -> IDSet a
    delete i = IDSet . IntSet.delete (unID i) . unIDSet
    

    So, assuming you have a Person type, and a Group type, you can do:

    type PersonID = ID Person
    type PersonIDSet = IDSet Person
    
    type GroupID = ID Group
    type GroupIDSet = IDSet Group
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Thanks for your attention and time. I'm modifying an existing JavaScript but can't understand
Thanks everyone for your answers. The one issue I am having though is when
Does D have 'newtype' (as in Haskell). It's a naive question, as I'm just
Thanks in advance for any help. :) Ok, here's my problem. Simplified version of
thanks for your attention and precious time. Please mention some free javascrpt obfuscator software
Thanks, for your help, I posted a simplified version of my problem but I
How can I use my Broadcast receiver? Like when my app starts how do
Thanks in advance. I want to get the pinch effect to an image means
Thanks in advance. I know crop an image using CGRect value and masking .But
Thanks to this excellent tutorial , I know how to read a string (in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.