4 ms·
Here's a very simple example: A user can have one of two roles: Normal or Admin. You can model this as: - User = Name x Password x Role - Role = Normal +
by noelwelsh 2y ago
Here's a very simple example:
A user can have one of two roles: Normal or Admin. You can model this as:
- User = Name x Password x Role
- Role = Normal + Admin
or you can multiply it out and get
- User = Admin or Normal
- Admin = Name x Password
- Normal = Name x Password
Which you should choose depends on the application. The second representation forces you to consider at every step if you have an Admin or Normal user, which is better for security. The first representation is more convenient when you don't care about the role.
I do these transformations a lot when modelling things. They are trivial, but if you don't understand the underlying algebra you might not see them (in the same way the developers who aren't used to sum types tend to be blind to them.)
Does that help?
- galaxyLogic 2y agoWhat would be User x Role? Is it (Name x Password x Role) x (Normal + Admin) = ? What data-structure would that represent?
- noelwelsh 2y agoIf User = Name x Password x Role and Role = Normal + Admin Then (Name x Password x Role) x (Normal + Admin) = (Name x Password x Role) x Role = Name x Password x Role x Role (See the normal rules of algebra apply) In Ocaml you would write type Something = User * Role or type Something = Name * Password * Role * Role In Typescript you would have something like type Something = { user: User, role: Role } or type Something = { name: Name, password: Password, role1: Role, role2: Role } These two types are isomorphic (they have the same structure when you ignore irrelevant details) but you'd program with them slightly differently. Neither type makes a great deal of sense, but it's what you asked for. :-)
- taeric 2y agoI'm not clear that I see the benefit of the techniques here? For one, it is not necessarily obvious that the "or (|)" is not a distributive property. It is, instead, a population description? As such, it seems like it leads to a very weird statements compared to what you would get in other uses. For example, if instead of Role, it was IsAdmin, and IsAdmin = True | False, then your application here gets you the odd True = Name x Password. What does that even mean? It also has an odd one of what if Role = Normal + Admin + SuperAdmin, but User is still Admin | Normal? What does that even mean?
- noelwelsh 2y agoOr is + (Writing or was a typo) User has a Name, Password, and a Role, which gives User = Name x Password x Role Role is Normal or Admin. Formally: Role = Normal + Admin Now substitute User = Name x Password x (Normal + Admin) Multiply out User = (Name x Password x Normal) + (Name x Password x Admin) I added an extra step where I named some of the components. If you understand how this can be represented in code as an algebraic data type, you will see these two different representations have different properties when you come to program with them. If you don't, I'm afraid this text box does not contain enough space. Chapter 2 of https://scalawithcats.com/ https://scalawithcats.com/ goes through this in much more detail.
- taeric 2y agoCool, was curious why you had + and "or". I was assuming both are the same as | in the linked article. (I am further assuming you are largely working on the "left hand side" per the article?) The rest of your math, I largely followed, but I can't see where `Normal = Name x Password` results. Nor do I see what it would communicate. This is why I dropped instead to Boolean = True | False. If I substitute that in your statements, I get `True = Name x Password`. And I don't see how that means anything. :(
- noelwelsh 2y agoName and Password are probably going to wrap the String type. Admin and Normal don't have data associated with them. They are just flags (or tags, depending on the terminology you are used to.) So when we write User = (Name x Password x Normal) + (Name x Password x Admin) we know that Normal and Admin distinguish two otherwise identical cases. So with a bit of substitution we can write User = Normal + Admin Normal = (Name x Password) Admin = (Name x Password) True + False is isomorphic to Normal + Admin, but if you aren't used to working in a language with algebraic data types you might not be used to thinking in this way. In Haskell you'd write something like data User = Normal Admin Password | Admin Name Password You could equally write data User = True Admin Password | False Name Password because True and False are just tags, distinct from their use in the boolean type. This would just really confusing to other programmers.