2016-06-18 2 views
9

Я пытался определить более общий случай для (!) Оператора следующим образом,F # Вызов инлайн функции с переменными типа

let inline (!) (cell : ^a) = 
    (^a : (member Value : ^b) cell) 

Так что он работает не только для ref типа, но любого типа с Value участник.

> !(ref 10) ;; 
val it : int = 10 

> !(lazy 5) ;; 
val it : int = 5 

Но проблема возникает, когда я пытаюсь применить его к типу с переменными типа,

> let getValue (c : 'a ref) = !c ;; 

    let getValue (c : 'a ref) = !c ;; 
    ------------------^^ 

C:\Users\User\AppData\Local\Temp\stdin(6,19): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'obj'. 

val getValue : c:obj ref -> obj 

в то время как он работает нормально, если я расширяю функцию инлайн.

> let getValue (c : 'a ref) = c.Value ;; 

val getValue : c:'a ref -> 'a 

Кто-нибудь знает, почему это происходит? Благодарю.

ответ

5

Поскольку ваша функция getValue не является встроенной, ограничения не будут работать.

Проблема заключается в том, что система типа .NET не может хранить тип ограничений, которые F # может использовать в inline.

В результате, если у вас есть не встроенная функция, которая использует встроенную функцию таким образом, вы получите сообщение об ошибке.

+0

Последняя версия 'getValue' является лишь ручным расширением прежней версии, хотя я знаю, что мне может что-то не хватает, но я все еще не вижу, как первый вводит больше ограничений типа, чем последний, что .NET может захват. – Doaz

+0

Я думаю, что ограничения на 'getValue' являются надмножеством ограничений на'! '. Поскольку ограничение ограничений на 'getValue' требует встроенного, оно не может быть нестрочной функцией –

 Смежные вопросы

  • Нет связанных вопросов^_^