Saya baru-baru ini mengalami situasi di mana saya harus melewati fungsi predikat ke fungsi lain, dan cukup sering logika yang saya cari pada dasarnya adalah "apakah nilai ini cocok dengan pola ini?"
Pencocokan pola tampaknya lebih disukai dalam deklarasi, do
blok, dan daftar pemahaman, tetapi ada sejumlah fungsi yang mengambil predikat a -> Bool
, di mana akan sangat berguna untuk melewati suatu pola. Sebagai contoh, takeWhile
, until
, find
, span
, dll
Sejauh ini saya sudah melakukan \a -> case a of MyCons _ -> True; otherwise -> False
, atau menulis fungsi bernama a la let myPred (MyCons _) = True; myPred _ = False in
tetapi mereka berdua tampak sangat jelek dan tidak terlalu idiomatis. Cara "jelas" (dan salah) akan menjadi sesuatu seperti \(MyCons _) -> True
tetapi itu melemparkan kesalahan karena menjadi parsial, secara alami, dan bahkan kemudian rasanya seperti harus ada cara yang lebih bersih.
Apakah ada cara yang lebih ringkas / bersih untuk melakukan hal semacam ini? Atau apakah saya melakukan sesuatu yang sepenuhnya salah?
let myPred...
gaya itu buruk , tetapi rasanya jauh lebih jelas daripada yang saya harapkan untuk ide yang sangat sederhana, yang membuat saya bertanya-tanya apakah saya menggonggong pohon yang salah.
maybe :: b -> (a -> b) -> Maybe a -> b
dan bool :: a -> a -> Bool -> a
, kemudian gunakan dengan fungsi penghasil Boolean sebagai argumen. misalnya myCons z f (MyCons x) = f x ; myCons z f _ = z
, lalu telepon myCons False (const True) aMyConsValue
. ini hampir seperti yang Anda tulis, hanya memiliki satu tingkat "tipuan" / "abstraksi" lagi melalui argumen fungsional, dimasukkan ke dalamnya.
let
klausa yang tidak Anda sukai - walaupun saya lebih sukawhere
klausa yang setara sehingga ini tidak mengacaukan definisi utama. Tentu saja jika Anda membutuhkan utilitas ini lebih dari sekali maka Anda akan mendefinisikannya sebagai fungsi tingkat atas.