Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record syntax and sum types

I have this question about sum types in Haskell.

I'd like to create a sum type which is comprised of two or more other types, and each of the types may contain multiple fields. A trivial example would be like this:

data T3 = T1 { a :: Int, b :: Float} | T2 { x :: Char } deriving (Show)

In my understanding, T1 and T2 are data constructors which use record syntax. It seems that the definition of T3 will grow as the number of fields in T1 or T2 increases. My question is that how to practically handle these sum type constructors if the number of fields are large? Or, is it a good idea to mix sum type with record syntax?

like image 318
liu3tao Avatar asked Dec 10 '22 16:12

liu3tao


1 Answers

I don't quite understand what concerns you have, but to answer the question in the last line: no, it is rather not a good idea to mix sum types with record syntax. Records in general remain a bit of a weak spot of the Haskell language; they don't handle scoping very well at all. It's usually fine as long as you just have some seperate types with different record labels, but as soon as sum types or name clashes come in it gets rather nasty.

In particular, Haskell permits you to use a record field accessor of the T1 constructor for any value of type T3print $ a (T2 'x') will compile without warnings, but give a rather hard to foresee error at runtime.

In your example, it fortunately looks like you can easily avoid that kind of trouble:

data T3 = T3_1 T1 | T3_2 T2
           deriving (Show)
data T1 = T1 { a :: Int
             , b :: Float}
           deriving (Show)
data T2 = T2 { x :: Char }
           deriving (Show)

Now, any deconstruction you could write will be properly typechecked to make sense.

And such a structure of meaningful, small specialised sub-types is generally better to handle than a single monolithic type, especially if you have many functions that really deal only with part of the data structure.

The flip side is that it gets quadratically tedious to unwrap the layers of constructors, but that's fortunately a solved problem now: lens libraries allow you to compose accessor/modifiers very neatly.

Speaking of solved problems: Nikita Volkov has come up with a really nice concept for entirely replacing the problem-ridden record syntax.


Um... actually these aren't subtypes in any proper sense of the word, but you get what I mean.

like image 151
leftaroundabout Avatar answered Dec 30 '22 03:12

leftaroundabout