Super generi c F # - может это HKT? - PullRequest
2 голосов
/ 09 июля 2020

Итак, я работаю над новым обобщенным c парсером аргументов CLI (в основном для моей выгоды, посмотрим, придумаю ли я что-нибудь полезное, достойное публикации).

Скажем так. Начнем с того, что у меня есть функция с такой сигнатурой: (ArgumentConfiguration<'a> -> string array -> 'a * string array - другими словами, у меня есть функция, которая извлекает и дает мне значение определенного настроенного аргумента и оставшихся элементов массива строк. Общий c тип 'a не ограничен, поэтому это может быть int, float, Foo и т. Д. В типе конфигурации есть функция Parse, которая возвращает все, что мне нужно.

Хорошо, круто. Следующее, что нужно сделать - это иметь структуру данных, которую пользователь может ввести, которая содержит все эти синтаксические анализаторы, и функцию, которая будет принимать эту структуру и возвращать ту же «форму» структуры, но вместо ArgumentConfiguration<'a> она просто возвращает 'a. Вот более конкретный пример:

(* Input Type *)
type ArgumentInput = {
  A: ArgumentConfiguration<float>
  B: ArgumentConfiguration<int>
  C: ArgumentConfiguration<boolean>
}

(* Expected return type that I don't want to specify - I want it inferred *)
type ParserResult = {
  A: float
  B: int
  C: boolean
}

Ключ заключается в следующем: я хочу, чтобы это было как можно более строго типизированным, но, очевидно, у меня повсюду разные типы разных аргументов. Я открыт для создания различных структур - может быть, карта подойдет? даже последовательность? Коллекции кажутся неправильным ответом, хотя если у меня будет ArgumentConfiguration<float> рядом с ArgumentConfiguration<int> et c.

Итак, учитывая всю эту информацию, вот мои вопросы:

  1. Какая структура данных будет хорошо работать для хранения этих данных, чтобы данные и тип могли быть преобразованы в функцию?
  2. Как будет работать сигнатура функции?
    • Поскольку я знаком с Typescript и с тем, как он работает (хотя я хочу, чтобы это было на F #), подпись, как я полагаю, будет похожа на type ParserFn = (config: Record<string, ArgumentConfiguration<any>>) => (args: string[]) => Record<string, any>;, за исключением того, что типы для каждой записи записи (а я не Я не думаю, что в Typescript есть хороший обходной путь для этого; просто использую TS, так как я знаю это лучше) самый опытный, мне интересно, наткнулся ли я на ограничение системы типов F # (поможет ли мне новый пользовательский поставщик типов?), и может ли язык, например Haskell или даже Idris, потребоваться для полного express logi c смотрю пишу.
...