Filling two type parameters with the same type


(^) #1

I have a type like

struct DistortedNoise<Source, Displacement> where Source:Noise,
Displacement:Noise
{
    let source:Source,
        displacement:Displacement

    init(source:Source, displacement:Displacement)
    {
        self.source = source
        self.displacement = displacement
    }

    init(source:Source)
    {
        self.source = source
        self.displacement = source
    }
}

and I get the error

Compile Swift Module 'Noise' (5 sources)
/home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source' is not
convertible to 'Displacement'
        self.displacement = source
                            ^~~~~~

How do I tell Swift that I want the same type fulfilling both Source and
Displacement?


(David Sweeris) #2

You could try putting that init in an extension "where Source == Displacement"

···

On Jul 8, 2017, at 21:06, Taylor Swift via swift-users <swift-users@swift.org> wrote:

I have a type like

struct DistortedNoise<Source, Displacement> where Source:Noise, Displacement:Noise
{
    let source:Source,
        displacement:Displacement

    init(source:Source, displacement:Displacement)
    {
        self.source = source
        self.displacement = displacement
    }

    init(source:Source)
    {
        self.source = source
        self.displacement = source
    }
}

and I get the error

Compile Swift Module 'Noise' (5 sources)
/home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source' is not convertible to 'Displacement'
        self.displacement = source
                            ^~~~~~

How do I tell Swift that I want the same type fulfilling both Source and Displacement?

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(somu) #3

Hi Taylor,

If both Source and Displacement are going to be Noise, you could use just one placeholder type.

class Noise {}

struct DistortedNoise<Item> where Item:Noise
{
    let source:Item,
    displacement:Item
    
    init(source:Item, displacement:Item)
    {
        self.source = source
        self.displacement = displacement
    }
    
    init(source:Item)
    {
        self.source = source
        self.displacement = source
    }
}

Regards,
Muthu


(Zhao Xin) #4

No, David, it is now allowed. "error: same-type requirement makes generic
parameters 'Source' and 'Displacement' equivalent".

Zhao Xin

···

On Sun, Jul 9, 2017 at 12:35 PM, David Sweeris via swift-users < swift-users@swift.org> wrote:

You could try putting that init in an extension "where Source ==
Displacement"

> On Jul 8, 2017, at 21:06, Taylor Swift via swift-users < > swift-users@swift.org> wrote:
>
> I have a type like
>
> struct DistortedNoise<Source, Displacement> where Source:Noise,
Displacement:Noise
> {
> let source:Source,
> displacement:Displacement
>
> init(source:Source, displacement:Displacement)
> {
> self.source = source
> self.displacement = displacement
> }
>
> init(source:Source)
> {
> self.source = source
> self.displacement = source
> }
> }
>
> and I get the error
>
> Compile Swift Module 'Noise' (5 sources)
> /home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source' is
not convertible to 'Displacement'
> self.displacement = source
> ^~~~~~
>
> How do I tell Swift that I want the same type fulfilling both Source and
Displacement?
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(David Sweeris) #5

Oh, I hate that error! If there was ever a time I've wanted to have a conversation with the compiler... "yes, mr compiler, I know the same type requirement makes them equivalent; that's why I wrote it! Please compile anyway."

Which version of the compiler/language are you using?

···

Sent from my iPhone

On Jul 8, 2017, at 21:39, Zhao Xin <owenzx@gmail.com> wrote:

No, David, it is now allowed. "error: same-type requirement makes generic parameters 'Source' and 'Displacement' equivalent".

Zhao Xin

On Sun, Jul 9, 2017 at 12:35 PM, David Sweeris via swift-users <swift-users@swift.org> wrote:
You could try putting that init in an extension "where Source == Displacement"

> On Jul 8, 2017, at 21:06, Taylor Swift via swift-users <swift-users@swift.org> wrote:
>
> I have a type like
>
> struct DistortedNoise<Source, Displacement> where Source:Noise, Displacement:Noise
> {
> let source:Source,
> displacement:Displacement
>
> init(source:Source, displacement:Displacement)
> {
> self.source = source
> self.displacement = displacement
> }
>
> init(source:Source)
> {
> self.source = source
> self.displacement = source
> }
> }
>
> and I get the error
>
> Compile Swift Module 'Noise' (5 sources)
> /home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source' is not convertible to 'Displacement'
> self.displacement = source
> ^~~~~~
>
> How do I tell Swift that I want the same type fulfilling both Source and Displacement?
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(David Sweeris) #6

Hmm... I just tried it in a playground, and it works:
struct DistortedNoise<Source, Displacement> {
  let source:Source,
  displacement:Displacement
  
  init(source:Source, displacement:Displacement)
  {
    self.source = source
    self.displacement = displacement
  }
  
}
extension DistortedNoise where Source == Displacement {
  init(source:Source)
  {
    self.source = source
    self.displacement = source
  }
}
let foo = DistortedNoise(source: 1) // DistortedNoise<Int, Int>
foo.source // 1
foo.displacement // 1

That's with Xcode 9b2, using the default Xcode 9.0 toolchain. With Xcode 8.3.3 and its default toolchain, the `let foo = ...` line outputs "__lldb_expr_2.DistortedNoise<Int, Int>" instead of just "DistortedNoise<Int, Int>", but that's just a more... I think the word is "qualified"... name for the same thing.

- Dave Sweeris

···

On Jul 8, 2017, at 9:39 PM, Zhao Xin <owenzx@gmail.com> wrote:

No, David, it is now allowed. "error: same-type requirement makes generic parameters 'Source' and 'Displacement' equivalent".

Zhao Xin

On Sun, Jul 9, 2017 at 12:35 PM, David Sweeris via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
You could try putting that init in an extension "where Source == Displacement"

> On Jul 8, 2017, at 21:06, Taylor Swift via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
>
> I have a type like
>
> struct DistortedNoise<Source, Displacement> where Source:Noise, Displacement:Noise
> {
> let source:Source,
> displacement:Displacement
>
> init(source:Source, displacement:Displacement)
> {
> self.source = source
> self.displacement = displacement
> }
>
> init(source:Source)
> {
> self.source = source
> self.displacement = source
> }
> }
>
> and I get the error
>
> Compile Swift Module 'Noise' (5 sources)
> /home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source' is not convertible to 'Displacement'
> self.displacement = source
> ^~~~~~
>
> How do I tell Swift that I want the same type fulfilling both Source and Displacement?
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org <mailto:swift-users@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Zhao Xin) #7

Please try this:

struct DistortedNoise<Source> where Source:Noise {

    typealias Displacement = Source

    let source:Source

    let displacement:Displacement

    init(source:Source, displacement:Displacement)

    {

        self.source = source

        self.displacement = displacement

    }

    init(source:Source)

    {

        self.source = source

        self.displacement = source

    }

}

Zhao Xin

···

On Sun, Jul 9, 2017 at 12:21 PM, somu subscribe via swift-users < swift-users@swift.org> wrote:

Hi Taylor,

If both Source and Displacement are going to be Noise, you could use just
one placeholder type.

class Noise {}

struct DistortedNoise<Item> where Item:Noise
{
    let source:Item,
    displacement:Item

    init(source:Item, displacement:Item)
    {
        self.source = source
        self.displacement = displacement
    }

    init(source:Item)
    {
        self.source = source
        self.displacement = source
    }
}

Regards,
Muthu

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Zhao Xin) #8

typealias now = not.

Zhao Xin

···

On Sun, Jul 9, 2017 at 12:39 PM, Zhao Xin <owenzx@gmail.com> wrote:

No, David, it is now allowed. "error: same-type requirement makes generic
parameters 'Source' and 'Displacement' equivalent".

Zhao Xin

On Sun, Jul 9, 2017 at 12:35 PM, David Sweeris via swift-users < > swift-users@swift.org> wrote:

You could try putting that init in an extension "where Source ==
Displacement"

> On Jul 8, 2017, at 21:06, Taylor Swift via swift-users < >> swift-users@swift.org> wrote:
>
> I have a type like
>
> struct DistortedNoise<Source, Displacement> where Source:Noise,
Displacement:Noise
> {
> let source:Source,
> displacement:Displacement
>
> init(source:Source, displacement:Displacement)
> {
> self.source = source
> self.displacement = displacement
> }
>
> init(source:Source)
> {
> self.source = source
> self.displacement = source
> }
> }
>
> and I get the error
>
> Compile Swift Module 'Noise' (5 sources)
> /home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source'
is not convertible to 'Displacement'
> self.displacement = source
> ^~~~~~
>
> How do I tell Swift that I want the same type fulfilling both Source
and Displacement?
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Zhao Xin) #9

Sorry Dave, I didn't notice that you said in `extension`. I just put the "where
Source == Displacement" to the original poster's code and the error showed.
My bad.

Zhao Xin

···

On Sun, Jul 9, 2017 at 1:56 PM, David Sweeris <davesweeris@mac.com> wrote:

Hmm... I just tried it in a playground, and it works:
struct DistortedNoise<Source, Displacement> {
  let source:Source,
  displacement:Displacement

  init(source:Source, displacement:Displacement)
  {
    self.source = source
    self.displacement = displacement
  }

}
extension DistortedNoise where Source == Displacement {
  init(source:Source)
  {
    self.source = source
    self.displacement = source
  }
}
let foo = DistortedNoise(source: 1) // DistortedNoise<Int, Int>
foo.source // 1
foo.displacement // 1

That's with Xcode 9b2, using the default Xcode 9.0 toolchain. With Xcode
8.3.3 and its default toolchain, the `let foo = ...` line outputs "
__lldb_expr_2.DistortedNoise<Int, Int>" instead of just "DistortedNoise<Int,
>", but that's just a more... I think the word is "qualified"... name
for the same thing.

- Dave Sweeris

On Jul 8, 2017, at 9:39 PM, Zhao Xin <owenzx@gmail.com> wrote:

No, David, it is now allowed. "error: same-type requirement makes generic
parameters 'Source' and 'Displacement' equivalent".

Zhao Xin

On Sun, Jul 9, 2017 at 12:35 PM, David Sweeris via swift-users < > swift-users@swift.org> wrote:

You could try putting that init in an extension "where Source ==
Displacement"

> On Jul 8, 2017, at 21:06, Taylor Swift via swift-users < >> swift-users@swift.org> wrote:
>
> I have a type like
>
> struct DistortedNoise<Source, Displacement> where Source:Noise,
Displacement:Noise
> {
> let source:Source,
> displacement:Displacement
>
> init(source:Source, displacement:Displacement)
> {
> self.source = source
> self.displacement = displacement
> }
>
> init(source:Source)
> {
> self.source = source
> self.displacement = source
> }
> }
>
> and I get the error
>
> Compile Swift Module 'Noise' (5 sources)
> /home/taylor/noise/sources/noise/noise.swift:576:29: error: 'Source'
is not convertible to 'Displacement'
> self.displacement = source
> ^~~~~~
>
> How do I tell Swift that I want the same type fulfilling both Source
and Displacement?
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users