haskell-webapps
haskell-webapps copied to clipboard
How to get Active/Inactive data constructors without prefixes?
Possible to remove the Tenant
and User
prefixes from the following without loss of type-safety?
data TenantStatus = TenantActive | TenantInactive
data UserStatus = UserActive | UserInactive | UserBlocked
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
data StatusType = User | Tenant
data Status (a :: StatusType) where
Active :: Status a
Inactive :: Status a
Blocked :: Status User
type UserStatus = Status 'User
type TenantStatus = Status 'Tenant
@mpickering is it possible to extend this to the following:
data TenantStatus = TenantActive | TenantInactive
data UserStatus = UserActive | UserInactive | UserBlocked
data CustomerStatus = CustomerActive | CustomerBlocked
Aren't they gonna live in separate namespaces anyway?
@mpickering I'm not sure if I was clear earlier. Basically, the GADT-based solution that you proposed, works well if each data-model (User
, Tenant
, or Customer
) has the same set of statuses. That might not always be the case, which is what I was trying to explain with the following:
data TenantStatus = TenantActive | TenantInactive -- doesn't have Blocked state
data UserStatus = UserActive | UserInactive | UserBlocked -- has all three state
data CustomerStatus = CustomerActive | CustomerBlocked -- doesn't have inactive state
@BartAdv not necessarily. Wouldn't it be easier to have a single module that defines all these types?
@saurabhnanda Yep, putting some types in common module seems to be widely accepted approach. But you just hit its limitation - after all, your problem is purely name resolution problem, right? Therefore, I think, the GADT trick would be overkill for that - you'd be fixing some language aspect by tossing some more advanced feature at it.
@BartAdv yes, you're right. But the question is slightly rhetorical in nature. Shouldn't it be easier to do stuff like this in Haskell?
The other purpose of this question is to discover any type-extension that makes this possible.
Well, maybe it should be easier. But Haskell isn't know for its powerful name resolution - after all, records remained main complaint the user had for some time.
I also don't think it's the issue of types being not expressive enough in this case (unless you want to write code that's polymorphic and you want to handle all XXXInactive statuses etc), that's why I wouldn't personally pursuit it.
unless you want to write code that's polymorphic and you want to handle all XXXInactive statuses etc
Not completely sure what you mean by this. Possible to share some code?
To be honest I'm not knowledgeable enough to know/prepare quick example of what could you potentially do with such an encoding - all I wanted to say is that only if you would need it for certain correctness guarantees, would it be worthy to explore.
Just my 2 cents!
@saurabhnanda we can have these data declared in different NameSpaces and if we do then we might have to alias the module when we import T.Active T.Inactive
I understand that TenantActive and TenantInactive isn't as clean as Active and Inactive. But I believe we will get use to it?
Like I mentioned in my email and phone conversation. I am embracing Haskell and going with it.