{-# LANGUAGE FlexibleInstances, FunctionalDependencies #-} newtype Qty a = Qty Float -- Dimensions data DMass data DMassFrac -- Quantities type Mass = Qty DMass type MassFrac = Qty DMassFrac class QMul a b c | a b -> c where (.*) :: a -> b -> c -- instance QMul Float (Qty a) (Qty a) where instance float ~ Float => QMul float (Qty a) (Qty a) where x .* (Qty y) = Qty (x*y) instance QMul Mass MassFrac Mass where (Qty x) .* (Qty y) = Qty (x*y) g = Qty 1 :: Mass kg = 1000 .* g :: Mass -- kg = (1000 :: Float) .* g -- Works fine main :: IO () main = return ()