I'm using Haskell and trying to write the following:
data Scale s = Scale s s
However, I want to make it so that s
must be something that of the Num type class, like Int or Double. Is that possible to do using Haskell and GHC?
Yes:
{-# LANGUAGE GADTs #-}
data Scale s where
Scale :: Num s => s -> s -> Scale s
However, it's generally considered best practice not to do this. Instead, put the Num
constraint only on the functions that use Scale
s and need the Num
constraint. Being relaxed about such constraints allows you to temporarily break the invariant where appropriate; e.g. it's common to wish for a Functor
instance for such a type, which is impossible if you constrain the constructor as above.
I had a similar situation with Point
type. But I thought not about constraints, I thought about how to do generalizing element type of my point. Then I understood if I'll have point type like this data Point a = Point a a
then I can do it instance of Functor, Applicative, Foldable and Traversable. And I'll can design function by standart general way. For example:
dist :: Floating a => Point a -> Point a -> a
dist a b = sqrt $ sum $ (^2) <$> ((-) <$> a <*> b)
And I had question. What is going on? :) If I add constraint (as you asked) I would not can design by this way and I would need to implement a lot of functions like pointSub
.
So, there is something to think about :)
Num s
constraint only at the functions that actually need the it. – Alec