Haskell supports overloaded values, where a single overloaded value can behave sort of like a superposition of values each with a different type. For example, here's a simple type class:
class Truthy t where
truthy :: Integer -> t
instance Truthy Integer where
truthy x = x -- some computation that results in an Integer
instance Truthy Bool where
truthy x = x /= 0 -- some computation that results in a Bool
Passing a number to
truthy returns an overloaded value of type
Truthy t => t. This same value can be used as an
Integer or a
Prelude> let y = truthy 17
Prelude> if y then y else 42
y is used in a
Bool context (the condition) and also in a numeric
then clause, which needs to match the type of the numeric
Haskell also uses lazy evaluation, so it isn't surprising that the two
truthy 17 are computed lazily. This means that while an overloaded
value is conceptually a bundle of values of different types, only the instances that are actually used perform computation.
Are there any programming languages that have overloaded values like this but which use strict evaluation?
If so, what are the evaluation semantics of overloaded values like? Are overloaded values:
- strict (meaning that you have to perform computations for instances you'll never use)
- non-strict (which would be inconsistent with non-overloaded values)
- something else?