Этот вопрос недавно возник на FPish еще раз.Похоже, что есть простое решение, которое не требует большого количества рефакторинга.Для этого требуется одна вспомогательная функция:
module Sitelet =
let Filter (ok: 'T -> bool) (sitelet: Sitelet<'T>) =
let route req =
match sitelet.Router.Route(req) with
| Some x when ok x -> Some x
| _ -> None
let link action =
if ok action then
sitelet.Router.Link(action)
else None
{ sitelet with Router = Router.New route link }
Предположим, у вас есть тип действия с несколькими случаями, некоторые из которых вы хотите защитить, а некоторые общедоступные:
type Action =
| Pub ..
| Priv ..
Фильтрация позволяет вам использоватьудобный Infer
комбинатор по всему типу, а затем безопасно суммировать защищенные и открытые части.Так как суммированные сайтлеты пробуются слева направо, защита будет применяться только там, где требуется:
let s1 =
Sitelet.Infer ..
|> Sitelet.Protect
|> Sitelet.Filter (function Priv _ -> true | _ -> false)
let s2 = Sitelet.Infer ..
Sitelet.Sum [s1; s2]
Без фильтрации защищенный сайтлет будет обрабатывать все запросы.Возможно, есть и другие решения для этого, в том числе рефакторинг и разбиение вашего типа Action
на несколько подтипов или написание веб-сайта вручную без использования Infer
.