The Expression Problem
1. Background
Read those references if you are not familiar yet (TODO: maybe add tl;dr; here)
2. Solution - Type Classes
I thought type classes solve the problem nicely. Here is the example in Haskell using type class
data Shape = Square Float | Circle Float area :: Shape -> Float area x = case x of │ Square side -> (side * side) │ Circle radius -> (3.14 * radius * radius)
“Solution” using Type Class
data Square1 = Square1 Float data Circle1 = Circle1 Float class Area a where │ area1 :: a -> Float instance Area Square1 where │ area1 (Square1 side) = side * side instance Area Circle1 where │ area1 (Circle1 r) = 3.14 * r * r
Thanks to Daniel, he pointed me that type class still has limitations. For instance
TODO: demo the limitation
I guess it is because Type Class doesn’t really solve the problem directly but work around a bit.
The original problem/ask is to extend a data type but with type class, that original (single) data type has been broken into multiple data types hence the limitation.
I gave another thought when comparing the OO approach (easy data extension but not operation extension), operations are part of the Class (data type) hence it is never a question at table to talk about operations for data type interaction.
3. Solution - Visitor pattern
3.1. Impl in TypeScript
3.2. Remarks
The solutions appear pretty much same as Type Class solution since the basic idea is same
- Break the single Data Type into multiple
- Use some sort of plumbing technique to glue those data type with operations
4. Read paper On Understanding Data Abstraction
- Read once but didn’t follow well. Maybe worth re-read.