There is no way to choose a different type according to a different argument value. However, you can select an arbitrary type depending on the argument type.
To illustrate, let’s break down how you’re using Int
in funcTest
into a data type that represents only your possible arguments.
data N = One | Two | Other
And you would have a One
, Two
, and Other
case in funcTest
. However, this isn’t good enough to satisfy the rule I mentioned above.
However, consider another way of looking at the argument set to funcTest
.
data One = One
data Two = Two
data Other = Other
Now I have types for the different arguments rather than just values. These I can relate to the desired return types as follows.
-- the first n -> z means "z depends on n";
-- it is solely about type variables
-- the second n -> z is the type of funcTest
class FuncTest n z | n -> z where
funcTest : n -> z
-- I've skipped your DataType1 et al because I can just use
-- whatever result types I want
instance FuncTest One Int where
funcTest One = 5
instance FuncTest Two Text where
funcTest Two = "hello"
instance FuncTest Other Decimal where
funcTest Other = 20.3
testFuncTest = script do
-- these equality tests all pass and are well-typed
funcTest One === 5
funcTest Two === "hello"
funcTest Other === 20.3
{- does not compile, due to type error
error:
• Couldn't match type ‘Int’ with ‘Text’
arising from a functional dependency between:
constraint ‘FuncTest One Text’ arising from a use of ‘funcTest’
instance ‘FuncTest One Int’ -}
-- funcTest One === "hello"
This technique is an important part of the core operations of Daml. For example, exercise
selects a return type depending on the contract type and choice type. It is not restricted to this order of determination, either: a result type can determine an argument type instead of the other way around. Or they can both determine each other.
I emphasize that an instance
is selected at compile time. However, unlike with overloads, you can write your functions in such a way that “pass along” the FuncTest
constraint and are thus polymorphic at compile-time themselves. createAndExercise
is such a function. You might be interested in this forum post for more on class
and instance
: