Как я могу выполнить «встроенное совпадение» в F#

#f#

#f#

Вопрос:

У меня есть функция

 let binaryOp load store op =
    (load 0, load 1) ||> op |> store 2
  

который считывает 2 значения из виртуальной памяти, применяет к ним двоичную операцию и записывает результат обратно в память. Типы аргументов следующие:

 load: (int -> 'a)
op: ('a -> int)
store: (int -> unit)
  

Как вы можете видеть, op ограничено для возврата int . Я хочу изменить это, чтобы op можно было возвращать все, что можно преобразовать в int . Обычно это не было бы проблемой, поскольку я мог бы просто сделать

 (load 0, load 1) ||> op |> int |> store 2
  

Проблема в том, что я также хочу поддерживать пользовательские преобразования, в частности, bool к int , которые разрешаются во время компиляции. Что-то вроде этого

 let inline toInt (x: ^a) =
    inline match x with
    | :? bool as b -> if b then 1 else 0
    | _ -> int x

let inline binaryOp load store op =
    (load 0, load 1) ||> op |> toInt |> store 2
  

где правильный параметр соответствия разрешен во время компиляции и встроен непосредственно на сайте вызова. Я выбрал inline match в целях иллюстрации, но меня устраивает все, что решает мою реальную проблему.

Возможно ли что-то подобное в F #?

Комментарии:

1. Неясно, чем ваше гипотетическое inline match отличается от обычного match . Не могли бы вы пояснить, пожалуйста?

2. @FyodorSoikin ну, мой пример не компилируется с обычным совпадением, потому что x это неограниченный универсальный тип, поэтому я не могу выполнить принудительное выполнение bool .

3. Что, если сначала поместить его в поле?

4. @FyodorSoikin Я бы хотел избежать этого, если это возможно. Я использую только примитивные типы, поэтому всегда будет выполняться боксирование, что в этом месте довольно плохо с точки зрения производительности. Лучше всего было бы исключить весь тест типа и перенести его на время компиляции.