Имеется несколько значений Option <'a>, существует ли хорошо известный шаблон для объединения нескольких функций' a -> 'b ->' b? - PullRequest
4 голосов
/ 29 мая 2019

У меня есть ряд функций 'arg -> 'entity -> 'entity для обновления неизменяемой сущности.

У меня есть серия соответствующих 'arg option аргументов, где, если аргумент Some, я должен вызвать соответствующую функцию обновления.

В настоящее время я реализовал это так:

// General utility function
// ('a -> 'b -> 'b) -> 'a option -> 'b -> 'b
let ifSome f argOpt entity =
  match argOpt with
  | Some arg -> f arg entity
  | None -> entity


// Function that accepts several option parameters
// (callbackUrl and authHeader are wrapped in option)
let updateWebhook callbackUrl authHeader webhook =
   webhook
   |> ifSome Webhook.setCallbackUrl callbackUrl
   |> ifSome Webhook.setAuthHeader authHeader

Мне нравится, насколько это просто, но, как это часто бывает с моими доморощенными функциональными решениями (особенно, когда универсальная функция является более универсальной, чем предложено в именах параметров, которые я придумал), я чувствую, что это просто особый случай более общей функциональной концепции - что я мог бы использовать некоторые существующие абстракции для выполнения той же задачи. Поэтому я удивляюсь:

  • Это признанный функциональный паттерн? Если да, есть ли у него имя, и могу ли я где-нибудь прочитать об этом больше?
  • Если нет, то есть ли (надеюсь, такая же простая) альтернатива, которая выполняет то же самое, используя "хорошо известные" функциональные абстракции / шаблоны?

1 Ответ

5 голосов
/ 29 мая 2019

Это просто Option.fold (точнее в данном случае Option.foldBack).Складки более широко известны как катаморфизмы.

let updateWebhook callbackUrl authHeader webhook =
   webhook
   |> Option.foldBack Webhook.setCallbackUrl callbackUrl
   |> Option.foldBack Webhook.setAuthHeader authHeader
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...