Di Haskell, saya bisa menggunakan tipe a -> Maybe b
untuk memodelkan fungsi yang mengembalikan nilai tipe b
, atau mengembalikan apa-apa (gagal).
Jika saya memiliki jenis a1, ..., a(n+1)
dan fungsi f1, ..., fn
, dengan fi :: ai -> Maybe a(i+1)
untuk semua i
, 1 <= i <= n
, aku dapat rantai fungsi dengan menggunakan >>=
operator Maybe
monad dan menulis:
f1 x >>= f2 >>= f3 >>=... >>= fn
The >>=
Memastikan operator yang masing-masing fungsi diterapkan selama pendahulunya telah kembali nilai yang berarti. Segera setelah fungsi dalam rantai gagal, seluruh rantai gagal (kembali Nothing
) dan fungsi lebih lanjut dalam rantai tidak dievaluasi.
Saya memiliki pola yang agak mirip di mana saya ingin mencoba beberapa fungsi pada input yang sama, dan kembali segera setelah satu fungsi berhasil . Jika semua fungsi gagal (kembali Nothing
), seluruh perhitungan harus gagal. Lebih tepatnya, saya memiliki fungsi f1, ..., fn :: a -> Maybe b
dan saya mendefinisikan fungsi
tryFunctions :: [a -> Maybe b] -> a -> Maybe b
tryFunctions [] _ = Nothing
tryFunctions (f : fs) x = case f x of
Nothing -> tryFunctions fs x
r@(Just _) -> r
Dalam arti tertentu, ini adalah ganda bagi Maybe
monad karena perhitungan berhenti pada keberhasilan pertama dan bukan pada kegagalan pertama.
Tentu saja, saya dapat menggunakan fungsi yang saya tulis di atas, tetapi saya bertanya-tanya apakah ada cara yang lebih baik, mapan dan idiomatis untuk mengekspresikan pola ini di Haskell.
Alternative
yang merupakan simbol operator infiks <|>
dan didefinisikan dalam istilah Monoid
return f1 ?? f2 ?? f3 ?? DefaultValue;