Ho un paio di frammenti che sembrano voler fare la stessa cosa, ma non sono del tutto convinto che ci sia un costrutto generalizzato per gestirli entrambi . In un unico luogo, hoCercare la generalizzazione del costrutto `se px then x else empty`
ensure :: (String -> Bool) -> String -> String
ensure p x =
if p x then
x
else
""
Questo potrebbe in uso aspetto qualcosa come
ensure (/= "kim") "alex" -- returns "alex"
ensure (/= "kim") "kim" -- returns ""
in un altro, ho il molto simile
ensure :: (a -> Bool) -> Maybe a -> Maybe a
ensure p maybeX = do
x <- maybeX
if p x then
Just x
else
Nothing
Questo sarebbe invece un aspetto simile
ensure even 6 -- returns Just 6
ensure even 11 -- returns Nothing
Entrambi sono cking se un valore è corretto secondo alcuni predicati, e se non lo è restituiscono un valore "vuoto" predefinito. C'è una leggera differenza anche se - il che significa che la seconda funzione potrebbe essere riscritta come
ensure :: (Maybe a -> Bool) -> Maybe a -> Maybe a
ensure p maybeX =
if p x then
x
else
Nothing
per renderli più simili, mettendo la responsabilità di "scartare" la Maybe
sul predicato. Con questa nuova definizione, entrambe le funzioni cadrebbero sotto
ensure :: Alternative f => (f a -> Bool) -> f a -> f a
ensure p x =
bool x empty (p x)
Quindi, la mia domanda è,
Fa questo bool x empty (p x)
esistono in qualche forma, quindi non c'è bisogno di implementare questa funzione me stesso? Il problema con inlining bool x empty (p x)
è che nel mio caso, sia p
sia x
sono piuttosto lunghi.
definirei 'ensure' come' assicurare :: MonadPlus m => (a -> bool) -> a -> M a; assicurare p = mfilter p. return'. – user3237465
'ensure' mi ricorda [' guard'] (http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html#v:guard) ma sembra molto più utile – Bergi
il secondo modulo sembra ['mfilter'] (http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html#v:mfilter). Passare un valore da scartare al predicato sembra essere migliore. – Bergi