@@ -32,6 +32,51 @@ then take a list of type `List[A]`, and return a list of the same type `List[A]`
32
32
33
33
[ More details] ( https://github.com/lampepfl/dotty/pull/4672 )
34
34
35
+
36
+ ### Example Usage
37
+
38
+ Polymorphic function type are particularly useful
39
+ when callers of a method are required to provide a
40
+ function which has to be polymorphic,
41
+ meaning that it should accept arbitrary types as part of its inputs.
42
+
43
+ For instance, consider the situation where we have
44
+ a data type to represent the expressions of a simple language
45
+ (consisting only of variables and function application)
46
+ in a strongly-typed way:
47
+
48
+ ``` scala
49
+ enum Expr [A ]:
50
+ case Var (name : String )
51
+ case Apply [A , B ](fun : Expr [B => A ], arg : Expr [B ]) extends Expr [A ]
52
+ ```
53
+
54
+ We would like to provide a way for users to map a function
55
+ over all immediate subexpressions of a given ` Expr ` .
56
+ This requires the given function to be polymorphic,
57
+ since each subexpression may have a different type.
58
+ Here is how to implement this using polymorphic function types:
59
+
60
+ ``` scala
61
+ def mapSubexpressions [A ](e : Expr [A ])(f : [B ] => Expr [B ] => Expr [B ]): Expr [A ] =
62
+ e match
63
+ case Apply (fun, arg) => Apply (f(fun), f(arg))
64
+ case Var (n) => Var (n)
65
+ ```
66
+
67
+ And here is how to use this function to _ wrap_ each subexpression
68
+ in a given expression with a call to some ` wrap ` function,
69
+ defined as a variable:
70
+
71
+ ``` scala
72
+ val e0 = Apply (Var (" f" ), Var (" a" ))
73
+ val e1 = mapSubexpressions(e0)(
74
+ [B ] => (se : Expr [B ]) => Apply (Var [B => B ](" wrap" ), se))
75
+ println(e1) // Apply(Apply(Var(wrap),Var(f)),Apply(Var(wrap),Var(a)))
76
+ ```
77
+
78
+
79
+
35
80
### Relationship With Type Lambdas
36
81
37
82
Polymorphic function types are not to be confused with
0 commit comments