Ambiguous use of functions (Swift 4)

I tried to find out why the following code is ambiguous ...

public func product <T1: Sequence, T2: Sequence> (_ sequence1: T1, _ sequence2: T2) -> AnySequence<(T1.Element, T2.Element)> { return AnySequence( sequence1.flatMap { element1 in sequence2.map { element2 in (element1, element2) } } ) } public func product <T1: LazySequenceProtocol, T2: LazySequenceProtocol> (_ sequence1: T1, _ sequence2: T2) -> LazySequence<AnySequence<(T1.Element, T2.Element)>> { return AnySequence( sequence1.flatMap { element1 in sequence2.map { element2 in (element1, element2) } } ).lazy } 

... when I call it two lazy sequences and call makeIterator EXAMPLE .

 _ = product([1, 2].lazy, [3, 4].lazy).makeIterator() 

However, the following code does not have this ambiguity ...

 public struct Product2Sequence <T1: Sequence, T2: Sequence>: Sequence { public typealias Element = (T1.Element, T2.Element) public typealias Iterator = AnyIterator<Element> private let iterator: Iterator internal init (_ sequence1: T1, _ sequence2: T2) { self.iterator = AnyIterator( sequence1.flatMap { element1 in sequence2.map { element2 in (element1, element2) } }.makeIterator() ) } public func makeIterator () -> Iterator { return self.iterator } } public struct LazyProduct2Sequence <T1: LazySequenceProtocol, T2: LazySequenceProtocol>: LazySequenceProtocol { public typealias Element = (T1.Element, T2.Element) public typealias Iterator = AnyIterator<Element> private let iterator: Iterator internal init (_ sequence1: T1, _ sequence2: T2) { self.iterator = AnyIterator( sequence1.flatMap { element1 in sequence2.map { element2 in (element1, element2) } }.makeIterator() ) } public func makeIterator () -> Iterator { return self.iterator } } public func product <T1: Sequence, T2: Sequence> (_ sequence1: T1, _ sequence2: T2) -> Product2Sequence<T1, T2> { return Product2Sequence(sequence1, sequence2) } public func product <T1: LazySequenceProtocol, T2: LazySequenceProtocol> (_ sequence1: T1, _ sequence2: T2) -> LazyProduct2Sequence<T1, T2> { return LazyProduct2Sequence(sequence1, sequence2) } 

... when I call it two lazy sequences and call makeIterator EXAMPLE .

 _ = product([1, 2].lazy, [3, 4].lazy).makeIterator() 

My reasoning is that a lazy sequence matches both LazySequenceProtocol and Sequence , so the type system does not know which product to choose. But by this definition, the second version should not work either.

I am using Swift 4.0.

What does the second version of the work do?

+8
functional-programming swift function-overloading swift4
source share

No one has answered this question yet.

See related questions:

1149
What is (functional) reactive programming?
1021
Is functional programming replacing GoF design patterns?
928
How do I call Objective-C code from Swift?
902
# pragma in Swift?
875
function for displaying objects (instead of arrays)
870
Fast beta: sorting arrays
703
Swift for loop: for index, element in array?
642
@selector () in Swift?
633
Functional programming versus object oriented programming
423
Using Swift 3 @objc output in Swift 4 mode is deprecated?