Сохранение частично примененной функции generic

Возможно ли частично применить функцию, такую ​​как bprintf, и предотвратить ее ограничение в зависимости от ее первоначального использования?

Я хотел бы сделать следующее:

let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder
append "%i" 10
append "%s" string_value

Ответ 1

вы можете добавить явный аргумент формата

let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"

Ответ 2

Аспект F #, вызывающий это, называется ограничением значения. Вы можете видеть, что если вы введете только две объявления let в F # Interactive (чтобы компилятор не выводил тип с первого использования):

> let builder = new System.Text.StringBuilder() 
  let append = Printf.bprintf builder ;;

ошибка FS0030: ограничение значения. Значение "append" было определено как     generic type val append: ('_a → ' _b), когда '_a: > Printf.BuilderFormat <' _ b >     Либо сделайте аргументы для "добавления" явным, либо, если вы не собираетесь     он будет общим, добавьте аннотацию типа.

отличная статья Дмитрия Ломова от команды F #, которая объясняет это подробно. Как следует из статьи, одним из решений является добавление объявления типа явного типа:

let builder = new System.Text.StringBuilder() 
let append<'T> : Printf.BuilderFormat<'T> -> 'T = Printf.bprintf builder 
append "%i" 10 
append "%s" "Hello"

Это будет работать нормально.