Creating Type Literals in scala eg. AplhaNumericSt

2019-08-07 03:35发布

问题:

At the moment I have a bunch of functions that check if strings meet certain circumstances eg isValidAlphaNumericString or isValidUserName. Which uses my own implicit stringOps class. It is quite useful especially when dealing with complex requirements such as author names etc. Requiring string to have only no consecutive -_. or space characters etc. Using complex regex's. But why stop there? The string isn't constrained properly meaning some function could map an anonymous function to it and break the variable after you have checked it. This is not a very safe way to proceed. I want a to create types for each of these constrained strings bound to a trait ConstrainedString which allows me to specify how each type deals with methods.

I'm struggling with the design side of it. Basically there's two things I need help with.

What happens when a function breaks the constraint? Is there a way to catch this at compile time? Do I restrict my type from only having methods that I know will not break the constraint ie. Concatenation of 2 AlphaNumericString's will always return alphanumeric String?? Or do I have the actual type as Option[String] so If the contract is broken the value becomes None?? There must be a better way aside from throwing exceptions everywhere.

Im presuming the best way to achieve this is through a StringLike typeclass similar to this example http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html eg

Except i want to be able to write

val foo:Bar = "This is a valid Bar"

I presume the appropriate way is to provide an implicit conversion of string to Bar by pointing to a Bar apply() method which checks if the method is a valid Bar. The dream is to have is work like Numbers do in scala and having this fail to compile.

//fails to compile due to - not being a valid character
val foo:AlphaNumericString = "-Adlsa85464"

If anyone has actually implemented something similar id love to look at the code otherwise:

Is there a simple way to maintain the constraint regardless of function issues

Is my theory on how to approach this issue correct?

回答1:

It seems like a good fit for Scala Macros. See this post for details. You can have your own string types and perform compile time validation on them.



回答2:

Imagine that you are a scala compiler :) How would you approach the task of failing an assignment like val foo: AlphaNumericString = someString() without actually evaluation the right hand side and the conversion function?

This was just my long way to say, that what you are asking for is obviously impossible.