Ответ 1
вы можете добавить явный аргумент формата
let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"
Возможно ли частично применить функцию, такую как bprintf
, и предотвратить ее ограничение в зависимости от ее первоначального использования?
Я хотел бы сделать следующее:
let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder
append "%i" 10
append "%s" string_value
вы можете добавить явный аргумент формата
let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"
Аспект 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"
Это будет работать нормально.
Вы сталкиваетесь с ограничением значения F #.
Вот хорошее объяснение некоторых обходных решений: Общие сведения об ошибках ограничения значения F #
Вот достаточно подробная статья, объясняющая причины этого: http://blogs.msdn.com/b/mulambda/archive/2010/05/01/value-restriction-in-f.aspx