Функция не может принимать значение статического параметра в качестве аргумента, потому что значение должно быть определено во время компиляции. Это означает, что если вы пишете:
let [<Literal>] sample = """{"name":"Peter","age":9}"""
let parseHtml html = JsonProvider<sample>.Parse(html)
... все нормально, потому что компилятор знает, что sample
является постоянным (и компилятор знает его значение), и поэтому он может создать экземпляр поставщика типа (во время компиляции) для генерации типов. Если вы пишете что-то вроде:
let parseHtml sample html = JsonProvider<sample>.Parse(html)
... то компилятор не может знать, что значение sample
может быть во время выполнения и поэтому он не может генерировать необходимые типы во время компиляции. Поставщики типов не «существуют» во время выполнения, поэтому типы не могут генерироваться «на лету» (это было бы не очень полезно, поскольку провайдеры типа типа должны предоставить вам некоторые гарантии безопасности во время компиляции).
Ваш пример. В вашем случае, это может иметь смысл взять конкретную JsonProvider<sample>.Parse
функцию в качестве аргумента вместо:
let SyncIt url parse storer =
async {
url
|> MakeRequestAsync
|> Async.RunSynchronously
|> parse
|> Seq.iter (converter >> storer)
}
Таким образом, абонент может указать статический параметр к провайдеру типа, а затем позвонить в вашу функцию, чтобы сделать синхронизацию :
let [<Literal>] sample = """{"name":"Peter","age":9}"""
SyncIt url (JsonProvider<sample>.Parse) storer
Хотя, не совсем понятно, почему вам нужен провайдер типа здесь. Пункт провайдеров - дать вам хорошие типы, которые вы можете использовать для доступа к конкретному источнику данных. Если ваши converter
и storer
работают на любом файле данных JSON, то вы могли бы сделать это, используя только JSON parser (also in F# Data).
Асинхронный блок. Кроме того, обратите внимание, что ваш код на самом деле не работает асинхронно - сделать это асинхронно, вам нужно загрузить URL с помощью let!
операции:
let SyncIt url parser storer =
async {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
parser html
|> Seq.iter (converter >> storer)
}
Это имеет смысл, спасибо! – Remko
Я добавил несколько подробностей. Я не совсем понял, почему вам нужно использовать поставщиков типов, если ваши «конвертер» и «хранитель» могут (по-видимому) работать на любом JSON - поэтому они не пользуются статически известными типами. –
Я нахожусь на своей второй неделе от f # и начать разбираться с некоторыми концепциями. Я использую typeprovider, потому что мне нравится, что большинство типов значений были распознаны. Конвертер отображает из DomainTypes.Entity тип записи, который я определил. Эта запись хранится в Redis.При попытке написать конвертер мне не удастся получить более одного возвращаемого типа. Спасибо за объяснение. Регс, Ремко – Remko