haskell-webapps icon indicating copy to clipboard operation
haskell-webapps copied to clipboard

How to get Active/Inactive data constructors without prefixes?

Open saurabhnanda opened this issue 7 years ago • 10 comments

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

saurabhnanda avatar Sep 04 '16 18:09 saurabhnanda

{-# 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 avatar Sep 04 '16 18:09 mpickering

@mpickering is it possible to extend this to the following:

data TenantStatus = TenantActive | TenantInactive
data UserStatus = UserActive | UserInactive | UserBlocked
data CustomerStatus = CustomerActive | CustomerBlocked

saurabhnanda avatar Sep 04 '16 19:09 saurabhnanda

Aren't they gonna live in separate namespaces anyway?

BartAdv avatar Sep 26 '16 14:09 BartAdv

@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 avatar Sep 29 '16 06:09 saurabhnanda

@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 avatar Sep 29 '16 07:09 BartAdv

@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.

saurabhnanda avatar Sep 29 '16 09:09 saurabhnanda

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.

BartAdv avatar Sep 29 '16 09:09 BartAdv

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?

saurabhnanda avatar Sep 29 '16 09:09 saurabhnanda

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.

BartAdv avatar Sep 29 '16 10:09 BartAdv

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.

sudhirvkumar avatar Oct 04 '16 08:10 sudhirvkumar