Guest User

Untitled

a guest
Feb 24th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.88 KB | None | 0 0
  1. // NOTE: This is an experiement that does not actually work (in the 2/8/18 nightly toolchain).
  2. // The idea is to use Swift's constraint inference to be able to abstract an arbitrary set of constraints.
  3.  
  4. /// An empty enum serving as an example of the general case of
  5. /// representing a set of constraints that relate multiple types.
  6. /// This specific example provides the constraint that both types are sequences and they have the same Element type.
  7. enum Parallel<S1: Sequence, S2: Sequence> where S1.Element == S2.Element {
  8. typealias First = S1
  9. typealias Second = S2
  10. }
  11.  
  12. /// A function that uses a phantom argument intended to get the compiler to infer the constraints
  13. /// represented by the Parallel.
  14. /// This seems to work but can produce extremely unhelpful error messages, far worse than the error messages
  15. /// that would be produced if the constraints were stated explicitly here. It is also rather verbose at the usage site.
  16. func foo<S1, S2>(_ s1: S1, _ s2: S2, constriants: Parallel<S1, S2>.Type = Parallel<S1, S2>.self) {
  17. print(s1)
  18. print(s2)
  19. }
  20.  
  21. // compiler allows this as expected
  22. foo([1, 2], [1, 2] as Set)
  23.  
  24. // Compiler rejects this with a useful error message:
  25. // - candidate requires that the types 'Int' and 'String' be equivalent (requirement specified as 'S1.Element' == 'S2.Element' [with S1 = [Int], S2 = Set<String>])
  26. // foo([1, 2], ["1", "2"] as Set)
  27.  
  28. // Compiler rejects this but with a non-obvious error message:
  29. // - cannot invoke 'foo' with an argument list of type '(Int, Int)'
  30. // - note: expected an argument list of type '(S1, S2, constriants: Parallel<S1, S2>.Type)'
  31. // foo(42, 43)
  32.  
  33. // Given the prior two examples it appears that the compiler infers the constraints on S1 and S2
  34. // as desired when the types both have Sequence conformances despite not meeting other constraints
  35. // specified by Parallel, but only omits the default argument when they do not have the conformances.
  36.  
  37. /// A function that uses a where clause intended to get the compiler to infer the constraints
  38. /// represented by the Parallel. Ideally this could simply be stated as Parallel<S1, S2>.
  39. func bar<S1, S2>(_ s1: S1, _ s2: S2) where S1 == Parallel<S1, S2>.First {
  40. print(s1)
  41. print(s2)
  42. }
  43.  
  44. foo([1, 2], [1, 2] as Set)
  45.  
  46. // Compiler unfortunately allows this.
  47. bar([1, 2], ["1", "2"] as Set)
  48.  
  49. // Compiler does not allow this but fails with the same unhelpful diagnostic as in foo(42, 43)
  50. //foo(42, 43)
  51.  
  52. /// A type that uses a where clause intended to get the compiler to infer the constraints
  53. /// represented by the Parallel. Ideally this could simply be stated as Parallel<S1, S2>.
  54. struct Pair<S1, S2> where S1 == Parallel<S1, S2>.First {
  55. let first: S1
  56. let second: S2
  57. }
  58.  
  59. print(Pair(first: [1, 2], second: [1, 2] as Set))
  60.  
  61. // As with bar, the compiler unfortunately allows this
  62. print(Pair(first: [1, 2], second: ["1", "2"] as Set))
  63.  
  64. // Again, unfortunately the compiler allows this
  65. print(Pair(first: 42, second: 43))
Add Comment
Please, Sign In to add comment