Я думаю, что интерфейсы, как правило, используются гораздо чаще, чем абстрактные классы (по сравнению с объектно-ориентированными языками, такими как C #).
Во многих случаях вам не нужно ничего из двух, потому что вы можете просто написать функцию высшего порядка (которая принимает функцию в качестве аргумента, а не принимает интерфейс в качестве аргумента). Однако иногда у вас могут быть две функции, которые всегда используются вместе - в этом случае вы можете сгруппировать две функции в интерфейс:
// Instead of using higher-order function
val foo : (int -> string) -> (string -> int) -> ...
// ..we can define an interface
type TwoWayConversion =
abstract ToString : int -> string
abstract FromString : string -> int
val foo : TwoWayConversion -> ...
Я думаю, что это довольно полезный шаблон программирования F #, который использует интерфейсы в совершенно функциональном стиле .
С другой стороны, я бы использовал абстрактные классы только при написании объектно-ориентированного кода, который предполагается использовать из C # (например, код C #, реализующий ваш абстрактный класс F #) - потому что это естественная точка расширяемости с точки C # Посмотреть. Однако я думаю, что идиоматический код F # использует точки расширяемости, отличные от C # (например, принимая функцию / интерфейс в качестве аргумента), поэтому вам не нужны абстрактные классы.