Home > database >  Is is possible to go parameterized variant with python's dataclasses?
Is is possible to go parameterized variant with python's dataclasses?

Time:06-25

Python's dataclasses is pretty cool, I've read some tutorial, and most of them look like

import dataclasses


@dataclasses.dataclass
class User:
    name: str
    age: int = 0

if __name__ == "__main__":
    u = User("taro", 32)


    match u:
        case User(name, age):
            print(f"{name}, {age}")

For people from OCaml world, I was wondering if maybe we could do parameterized variant like things with dataclasses?

#
type 'a mtype =
  | Empty
  | Cons of 'a * 'a mtype
;;

# let (musage: int mtype) = Cons (1, Cons (2, Empty));;
val musage : int mtype = Cons (1, Cons (2, Empty))

CodePudding user response:

In OCaml, mtype alone is not a type. You could think of it as a function over types, like mtype : type -> type, in the sense that given a type 'a, it will monomorphise in a concrete type 'a mtype. This requires "special" syntax because, in OCaml, operating on types like that cannot be done by any function anyhow. In Python, on the other hand, there is absolutely no such restriction: everything is an object, including types. So really creating a generic dataclass is as easy as:

def User(ty):
    @dataclass
    class User:
        name: str
        age: ty
    return User

Of course, this solution may not be completely satisfactory. For instance, one thing you may dislike is that it will produce ugly class names:

>>> User(int)
<class '__main__.User.<locals>.User'>
>>> User(int)("hello", 3)
User.<locals>.User(name='hello', age=3)
>>>

However, with Python's flexibility, it shouldn't be hard for you circumvent this kind of issues.


Besides that, as @Chris pointed out, Python is not a statically typed language (and not functional either), so beware of just translating literally OCaml code, in the sense that having generic dataclass is something I have never encountered before, probably because it's not that useful in Python.

CodePudding user response:

Bear in mind that Python is not statically typed. Python refers to those notations as 'hints' not 'rules' as they most certainly are in languages like OCaml.

>>> User(456.7, [3,4,5])
User(name=456.7, age=[3, 4, 5])
>>>
  • Related