error: value of type 'Self.SubSequence' has no member 'Distance'


(Daniel Eggert) #1

I have an array of String and need to call withCString on each one and then pass the resulting array of UnsafePointer<Int8> to a C api. The unsafe pointer is only valid within the scope of withCString.

So I built the following, but the compiler doesn’t like it:

% swift scopedReduceAndApply.swift
scopedReduceAndApply.swift:18:16: error: value of type 'Self.SubSequence' has no member 'Distance'
        return tail.scopedReduceAndApply(f, g: g, list: ll)
               ^~~~ ~~~~~~~~~~~~~~~~~~~~

What is ‘Distance’ and why doesn’t SubSequence of CollectionType have it?

/Daniel

extension CollectionType where SubSequence : CollectionType {
  /// Calls `f` for each Element to (scoped) generate a value of type `A`
  /// and pass it to the given function (3rd argument to `f`).
  /// The array of all generated `A` values will then be passed to the function
  /// `g`. Its return value will be returned by `scopedReduce`.
  ///
  /// This is similar to `reduce` but the function `g` is called while all calls
  /// to `f` are on the stack, i.e. are in scope. This allows `f` to call a
  /// function such as `String.withCString` and ensure that we're in its scope.
  private func scopedApply<A,B>(f: (Generator.Element, (A) -> B) -> B, g: [A] -> B) -> B {
    return scopedReduceAndApply(f, g: g, list: [])
  }
  private func scopedReduceAndApply<A,B>(f: (Generator.Element, (A) -> B) -> B, g: [A] -> B, list: [A]) -> B {
    if let (head, tail) = decompose {
      return f(head) { (a: A) -> B in
        var ll = list
        ll.append(a)
        return tail.scopedReduceAndApply(f, g: g, list: ll)
      }
    } else {
      return g(list)
    }
  }
}

extension CollectionType {
  var decompose: (head: Generator.Element, tail: SubSequence)? {
    if self.isEmpty {
      return nil
    } else {
      return (self[startIndex], self[startIndex.successor()..<endIndex])
    }
  }
}


(Dmitri Gribenko) #2

I have an array of String and need to call withCString on each one and then pass the resulting array of UnsafePointer<Int8> to a C api. The unsafe pointer is only valid within the scope of withCString.

So I built the following, but the compiler doesn’t like it:

% swift scopedReduceAndApply.swift
scopedReduceAndApply.swift:18:16: error: value of type 'Self.SubSequence' has no member 'Distance'
        return tail.scopedReduceAndApply(f, g: g, list: ll)
               ^~~~ ~~~~~~~~~~~~~~~~~~~~

What is ‘Distance’ and why doesn’t SubSequence of CollectionType have it?

That's just a bad error message.

extension CollectionType where SubSequence : CollectionType {

I think you need this constraint to be propagated all the way down,
for recursive calls, so you need:

extension CollectionType where SubSequence == Self

Or, if you want to allow the toplevel type to differ:

extension CollectionType
  where
  SubSequence : CollectionType,
  SubSequence.SubSequence == SubSequence

Dmitri

···

On Wed, Dec 23, 2015 at 3:24 PM, Daniel Eggert via swift-users <swift-users@swift.org> wrote:

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Daniel Eggert) #3

Thanks. That did the trick.

/Daniel

···

On 24 Dec 2015, at 03:11, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Wed, Dec 23, 2015 at 3:24 PM, Daniel Eggert via swift-users > <swift-users@swift.org> wrote:

I have an array of String and need to call withCString on each one and then pass the resulting array of UnsafePointer<Int8> to a C api. The unsafe pointer is only valid within the scope of withCString.

So I built the following, but the compiler doesn’t like it:

% swift scopedReduceAndApply.swift
scopedReduceAndApply.swift:18:16: error: value of type 'Self.SubSequence' has no member 'Distance'
       return tail.scopedReduceAndApply(f, g: g, list: ll)
              ^~~~ ~~~~~~~~~~~~~~~~~~~~

What is ‘Distance’ and why doesn’t SubSequence of CollectionType have it?

That's just a bad error message.

extension CollectionType where SubSequence : CollectionType {

I think you need this constraint to be propagated all the way down,
for recursive calls, so you need:

extension CollectionType where SubSequence == Self

Or, if you want to allow the toplevel type to differ:

extension CollectionType
where
SubSequence : CollectionType,
SubSequence.SubSequence == SubSequence