Hi all, I’ve been playing with PureScript to build a data validation library. Specifically, I wanted a library that gave me all the ergonomics of a dynamic language, but type-safe (of course). After brainstorming my ideal API design, I couldn’t think of a language that it would work in besides PureScript!
Suppose our schema looks like this:
type Student = { studentId :: Int, name :: String, age :: Int }
type School = { name :: String
, age :: Int
, students :: Array Student
}
Suppose each student needs to be at least 10 years old, there needs to be at least 5 students, and both the school and the students’ names must be non-empty. Then I want to be able to create a validation object that looks like this:
studentValidator = { name: [ notEmpty ], age: [ atLeast 10 ] }
schoolValidator = { name: [ notEmpty ]
, students: [ lengthAtLeast 5
, each studentValidator
]
}
where each validation rule is a simple function, like
notEmpty s = if s == "" then FieldError "can't be empty" else Ok
and then run validate schoolValidator mySchool
to get an error object back out that mirrors the schema of the validator.
I’ve spent the last few days trying to figure out the row type machinery well enough to make this work. I have a really, really bad and ugly prototype currently at here. There’s still some big warts with the ergonomics related to type specialization, and I’m sure my code is really redundant and inelegant since I basically got it to work by adding more and more class constraints until the typechecker stopped complaining. Also, I need to do way more testing, so there may be horrible bugs still. Nevertheless, I thought you guys might be interested - I don’t think any other static language has a flexible enough type system to do this without using macros or upcasting everything to Objects.