{-# LANGUAGE TypeData, TypeFamilies #-} type PlaintextPass = String type EncodedPass = Int type data UserType = Full | Patch | Create type family XUserId (x::UserType) type family XUserName (x::UserType) type family XUserPass (x::UserType) type family XUserBirth (x::UserType) type family XUserFriends (x::UserType) data User' (x :: UserType) = MkUser { userId :: XUserId x , userUserName :: XUserName x , userPassword :: XUserPass x , userBirthday :: XUserBirth x , userFriends :: XUserFriends x } type instance XUserId Full = Int type instance XUserName Full = String type instance XUserPass Full = EncodedPass type instance XUserBirth Full = String type instance XUserFriends Full = [Int] type User = User' Full deriving instance Show User type instance XUserId Create = () type instance XUserName Create = String type instance XUserPass Create = PlaintextPass type instance XUserBirth Create = String type instance XUserFriends Create = [Int] --etc... example :: User example = MkUser 0 "Frank" 1 "01-01-0001" [] main = print example