Suppose I have a custom type wrapping an existing type,
newtype T = T Int deriving Show
and suppose I want to be able to add up T
s, and that adding them up should result in adding the wrapped values up; I would do this via
instance Num T where
(T t1) + (T t2) = T (t1 + t2)
-- all other Num's methods = undefined
I think we are good so far. Please, tell me if there are major concerns up to this point.
Now let's suppose that I want to be able to multiply a T
by an Int
and that the result should be a T
whose wrapping value is the former multiplied by the int; I would go for something like this:
instance Num T where
(T t1) + (T t2) = T (t1 + t2)
(T t) * k = T (t * k)
-- all other Num's methods = undefined
which obviously doesn't work because class Num
declares (*) :: a -> a -> a
, thus requiring the two operands (and the result) to be all of the same type.
Even defining (*)
as a free function poses a similar problem (i.e. (*)
exists already in Prelude
).
How could I deal with this?
As for the why of this question, I can device the following
- in my program I want to use
(Int,Int)
for 2D vectors in a cartesian plane,
- but I also use
(Int,Int)
for another unrelated thing,
- therefore I have to disambiguate between the two, by using a
newtype
for at least one of them or, if use (Int,Int)
for several other reasons, then why not making all of them newtype
s wrapping (Int,Int)
?
- since
newtype Vec2D = Vec2D (Int,Int)
represents a vector in the plain, it makes sense to be able to do Vec2D (2,3) * 4 == Vec2D (8,12)
.
question from:
https://stackoverflow.com/questions/65641353/what-is-the-correct-way-to-define-an-already-existing-e-g-in-prelude-operator 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…