F #: Передача функции в Option.bind - PullRequest
0 голосов
/ 28 октября 2018

У меня есть функция great, и она реализована, как показано ниже

let great y z = Option.bind (cons (Option.get z) >> Some) y

И у меня есть функция, применяемая, как показано ниже

let apply f val = 
  match f with
  | None -> None
  | Some v -> Option.map v val 

Если я даю значение Noneдля второго параметра (z) он дает мне ошибку, так как Option.get z возвращает ошибку, когда получает None.

Я хочу избежать этой ошибки, не используя блоки if else.Интересно, можно ли передать применяемую функцию great, чтобы она могла оценивать None, когда заданный параметр z равен None.

Будет признательна любая помощь.

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Вы также можете написать отличную функцию, используя сопоставление с образцом, как функция применения.

let great lOpt xOpt = 
    match lOpt, xOpt with
    | Some l, Some x -> Some (x :: l)
    | Some l, None   -> Some l
    | _              -> None
0 голосов
/ 28 октября 2018

Если вы хотите выполнить всю вещь Option.bind ... только тогда, когда z равен Some, вы можете просто использовать для этого еще один Option.bind - это именно то, для чего bind предназначен:

let great y maybeZ = 
    Option.bind (fun z -> Option.bind (cons z >> Some) y) maybeZ

Или, чтобы выразить это более элегантно:

let great maybeY maybeZ = 
    maybeZ |> Option.bind (fun z -> 
    maybeY |> Option.bind (cons z >> Some) )

Первая строка будет выглядеть так: "bind MaybeZ с z, и ..."

На самом деле, я бы, наверное,проделайте то же самое с y только для дополнительной читабельности:

let great maybeY maybeZ = 
    maybeZ |> Option.bind (fun z -> 
    maybeY |> Option.bind (fun y ->
    Some (z :: y) ) )

В качестве альтернативы вы можете использовать Option.map2, что делает именно это: применяет функцию к двум option типизированным параметрам, когда обаSome:

let great maybeY maybeZ = 
    Option.map2 (fun y z -> z :: y) maybeY maybeZ

И затем вы можете уменьшить ее (но, к сожалению, только на maybeZ, из-за ограничения значения):

let great maybeY = 
    Option.map2 (fun y z -> z :: y) maybeY

Или вывместо этого можно избавиться от лямбды, если вы просто изменили параметры:

let great maybeY maybeZ = 
    Option.map2 cons maybeZ maybeY
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...