Допустим, я хотел бы иметь псевдоним sprintf
, я бы просто сделал это:
namespace FSharp
module Core =
let specialsprintf x y =
sprintf x y
Это принесло бы мне те же преимущества во время компиляции (по сравнению с C# API двоюродного брата System.String.Format
) функции sprintf, такой как проверка типов, проверка количества переданных параметров, и т. Д. c.
Однако, скажем, я хотел отключить эти тонкости времени компиляции и написать простую версию sprintf, вызвав String.Format внизу. Это могло быть возможно? Я знаю, что цель звучит глупо, но я хочу выполнить это умственное упражнение, чтобы убедиться, что я понимаю, как здесь работает F #. Если я сделаю это (предположим, что мы можем передать только один параметр):
namespace FSharp
module Core =
let specialsprintf x y =
#if NORMAL_FSHARP
sprintf x y
#else
let x = x.Replace("%s", "{0}")
System.String.Format(x,y)
#endif
Он даже не компилируется, ошибка:
~/FSharpPlayground.fs(17,17): Error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. (FS0072) (FSharpPlayground)
Мммм, почему?
Хорошо, если я укажу тип следующим образом:
namespace FSharp
module Core =
let specialsprintf
#if NORMAL_FSHARP
x
#else
(x: string)
#endif
y =
#if NORMAL_FSHARP
sprintf x y
#else
let x = x.Replace("%s", "{0}")
System.String.Format(x,y)
#endif
Тогда я получу ошибку компиляции в вызывающей программе:
~/FSharpPlaygroundUse.fs(48,48): Error FS0001: This expression was expected to have type 'obj []' but here has type 'string' (FS0001)
Полагаю, мне нужно теперь квалифицировать типа y
сейчас, но я не уверен, как это сделать, на случай, если я захочу расширить его, чтобы иметь возможность использовать 2 аргумента вместо 1 (мне не удается заставить его работать с атрибутом ParamArray
). Что-то подсказывает мне, что мне, вероятно, также нужна функция uncurry
, но я немного растерялся: - /