@@ -32,6 +32,51 @@ then take a list of type `List[A]`, and return a list of the same type `List[A]`
3232
3333[ More details] ( https://github.com/lampepfl/dotty/pull/4672 )
3434
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+
3580### Relationship With Type Lambdas
3681
3782Polymorphic function types are not to be confused with
0 commit comments