Di recente mi sono imbattuto in situazioni in cui ho bisogno di passare una funzione predicata in un'altra funzione, e molto spesso la logica che sto cercando è essenzialmente "questo valore corrisponde a questo modello?"
La corrispondenza dei modelli sembra essere preferita nelle dichiarazioni, nei do
blocchi e nelle comprensioni di elenchi, ma ci sono un certo numero di funzioni che accettano un predicato a -> Bool
, dove sarebbe molto utile passare in qualche modo in un modello. Ad esempio, takeWhile
, until
, find
, span
, etc.
Finora ho fatto \a -> case a of MyCons _ -> True; otherwise -> False
, o ho scritto una funzione con nome let myPred (MyCons _) = True; myPred _ = False in
ma entrambi sembrano terribilmente brutti e non molto idiomatici. Il modo "ovvio" (e sbagliato) sarebbe qualcosa di simile \(MyCons _) -> True
ma che genera un errore per essere parziale, naturalmente, e anche allora sembra che ci debba essere un modo più pulito.
C'è un modo più conciso / pulito per fare questo genere di cose? O sto andando sulle cose completamente nel modo sbagliato?
let myPred...
stile sia cattivo , ma sembra molto più dettagliato di quanto mi aspetterei per un'idea molto semplice, il che mi porta a chiedermi se sto abbaiando sull'albero sbagliato.
maybe :: b -> (a -> b) -> Maybe a -> b
e bool :: a -> a -> Bool -> a
, quindi, usarla con le funzioni che producono booleane come argomenti. ad es. myCons z f (MyCons x) = f x ; myCons z f _ = z
, quindi chiama myCons False (const True) aMyConsValue
. questo è quasi ciò che hai scritto, ha solo un altro livello di "indiretta" / "astrazione" tramite argomenti funzionali, inserito in esso.
let
clausola che non ti piace, anche se preferisco lawhere
clausola equivalente in modo da non ingombrare la definizione principale. Ovviamente se finisci per aver bisogno di questa utility più di una volta, la definiresti come una funzione di livello superiore.