В последней строке следующего фрагмента кода, я получаю два предупреждения: This construct causes code to be less generic than indicated by the type annotations. The type variable 'c has been constrained to be type ''a'.
и This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a * 'a'.
F умозаключение # типа менее общие, чем указано в аннотации типа
type SomeBaseClass<'a>() =
class end
type SomeClass<'a when 'a:equality> (getValue:unit->'a, ?arg2:SomeBaseClass<'b>) =
inherit SomeBaseClass<'a*'a>()
member this.Value with get() = getValue()
member this.Transform (transformation:'a->'c) =
let func():'c = transformation this.Value
SomeClass<'c> (func, this) // warnings are attached to this line
Это, с другой стороны, компилирует без проблем:
type SomeOtherClass<'a when 'a:equality> (getValue:unit->'a) =
inherit SomeBaseClass<'a*'a>()
member this.Value with get() = getValue()
member this.Transform (transformation:'a->'c) =
let func():'c = transformation this.Value
SomeOtherClass<'c> func
Я не вижу ничего предотвращения transformation
от возвращения другого типа, чем он пропускается. Я также не понимаю, почему это второе предупреждение является даже предупреждением, потому что уже очевидно, что для параметра 'b
для нового экземпляра явно будет 'a*'a
.
Что я здесь делаю неправильно?
Это устраняет предупреждение, но имеет побочный эффект от того, что каждый экземпляр SomeClass имеет два типа параметров вместо одного, который не является дополнительной сложностью, которую я ищу с дополнительным параметром, который не сохраняется как поле экземпляра. Есть ли способ дать конструктору аргумент типа, который сам класс не имеет или мне нужно использовать статическую функцию или что-то вместо этого? – Flaise
@Flaise 'SomeClass' обычно должен иметь два параметра типа, если его конструктор имеет их. Представьте себе выражение типа Array.zeroCreate <'b> 8' где-то в типе; его результат не будет правильно определен в системе типов F # без аргумента второго типа. Но точный тип 'SomeClass' часто можно вывести. Я отредактировал ответ, так что он опускает аргументы типа в вызове конструктора. Конечно, это менее вероятно, если один из параметров является необязательным; второй тип должен быть ясен из другого контекста, чем конструктор. – Vandroiy
Так что я не могу параметризовать/просто/конструктор - конструктор принимает те же аргументы типа, что и весь класс? Я просто использую статическую функцию, так как .NET сохраняет информацию о типе во время выполнения, что мешает отладке и производительности. – Flaise