Closed Vlix closed 4 years ago
This seems like a good idea.
Maybe in the future, we could export the constructor in a module like Data.Password.Internal
, but for now just hiding the constructor seems like a good idea.
Also, I'm wondering what the added value is of having a Read
instance for Pass
. If it has an IsString
instance, you can just fromString foo
where foo :: String
. Any read function is also from a String
, so it's superfluous AND because it makes more sense to implement a Show
function (see below), you'd rather not have a Read
and Show
that are not isomorphic.
Defining the Show
instance as follows:
instance Show Pass where
show _ = "**PASSWORD**"
This way no one can make their own Show
function for Pass
(maybe without thinking it through, just to make something type check) and forcing the user, again, to use a function labeled unsafe
to get to print the password.
I am kind of on the fence with having a Show
instance for Pass
.
On one hand, I don't want people to ever get lax about just show
ing a Pass
. I'd like users to explicitly have to use the unsafe functions if they want to go from Pass
to String
(even if show
doesn't actually show the password).
On the other hand, it is really annoying when types don't implement a Show
instance. It becomes very slightly harder to implement a Show
instance for any record containing a Pass
.
I guess I'd be okay with adding a Show
instance as long as there is a warning in the documentation about exactly what it does.
you'd rather not have a Read and Show that are not isomorphic
I don't really buy into the Read
/ Show
isomorphism law. Especially in cases like this where it could make sense to keep them different.
Now that I've taken a look at it, I think the bigger problem is that there is no documentation about what format the Read
function is expecting. And it is hard to figure out because there is also no show
instance.
To sum up, I guess I don't really care about Show
and Read
, but if they do exist, they should have good documentation!
To make it more safe, it'd be better that the
Pass
data constructor not be exported. This way, users can't pattern match on it and just remove theText
without using a function that's clearly labeled asunsafe
.Obviously, accompanying this should be a function like
mkPass :: Text -> Pass
to have users still be able to produce aPass
.