If you want errors to behave more like value types, you can also implement `Is`. For example, you could have your `ErrType`'s `Is` implementation return true if the other error `As` an `ErrType` also has the same code.
If you have a value type, you don't need to implement Is. It's just that errors.New (and fmt.Errorf) doesn't return a value type, so such errors only match under errors.Is if they have the same identity, hence why you typically see them defined with package-level sentinel variables.