Public extension method in extension with internal requirements

(^) #1

I have several public structs that conform to this internal protocol. The
protocol has an associated type IntV so that it can service 2, 3, or 4
dimensional noise.

protocol HashedTilingNoise
    associatedtype IntV

    var amplitude:Double { get }
    var frequency:Double { get }
    var wavelengths:IntV { get }

    init(amplitude:Double, frequency:Double, wavelengths:IntV)

I extend it to provide common functionality for all the conforming structs.

extension HashedTilingNoise
    func amplitude_scaled(by factor:Double) -> Self
        return Self(amplitude: self.amplitude * factor, frequency:
wavelengths: self.wavelengths)

    func frequency_scaled(by factor:Double) -> Self
        return Self(amplitude: self.amplitude, frequency: self.frequency *
factor, wavelengths: self.wavelengths)


But now I want to provide common functionality just for structs with a
certain dimension. For example, I want to provide a transpose(octaves:)
function for the structs that have 3 dimensional wavelengths.

extension HashedTilingNoise where IntV == Math.IntV3
    func transposed(octaves:Int) -> Self
        return Self(amplitude: self.amplitude, frequency: self.frequency,
                    wavelengths: (self.wavelengths.a << octaves,
<< octaves, self.wavelengths.c << octaves))

But this gives the compiler error

/home/taylorswift/noise/sources/noise/hash.swift:67:5: error: cannot
declare a public instance method in an extension with internal requirements

Because the Math.IntV3 type and the HashedTilingNoise protocol are
internal. I don’t want to expose these as part of the API as they are just
containers for shared functionality.

How do I fix this?