Dianjurkan agar Anda membaca
artikel pertama jika Anda belum melakukannya. Artikel ini akan lebih pendek, kurang fokus pada detail dan lebih banyak pada kemampuan.
Menurut
Stephen Diel , bersama dengan tipe dependen, kompilasi lebih cepat dan ambang masuk yang lebih rendah; efek aljabar adalah salah satu tugas paling penting yang akan diselesaikan di masa depan untuk Haskell.
Masa depan tidak jauh, jadi Anda harus mulai sekarang.
Meningkatkan Efek ke Efek Lain
class Liftable eff schema where lift :: eff ~> schema
Apa yang dimaksud dengan "peningkatan" pada intinya?
lift adalah
murni /
kembali sama, dengan pengecualian bahwa kita tidak merendam nilai dalam efek, tetapi efek dalam beberapa jenis transformator (dalam kasus kami, dalam rangkaian transformator):
pure :: a -> ta lift :: ua -> tua
Ini memungkinkan kita untuk menggunakan efek apa pun di dalam transformator tertentu - mudah untuk memperkenalkan efek baru, tetapi nanti kita perlu menafsirkan masing-masing dari mereka.
Dengan demikian, kita dapat menyusun efek yang diangkat dengan aman:
let f = lift get :: Configured _ t => t _ let g = lift Nothing :: Optional t => t _ let h = lift (failure _) :: Failable _ t => t _ let x = f *> g *> h :: (Applicative t, Configured _ t, Optional t, Failable _ t) => t _
Dan kirimkan dalam urutan yang nyaman bagi kami:
let y = pure _ :: Reader _ :> State _ :> Either _ :> Maybe := Int let z = pure _ :: State _ :> Either _ :> Maybe _ :> Reader := _ let x = f *> g *> h :: (Applicative t, Configured _ t, Optional t, Failable _ t) => t _ let xy = x *> y :: Reader _ :> State _ :> Either _ :> Maybe := _ let xz = x *> z :: State _ :> Either _ :> Maybe _ :> Reader := _
Adaptasi beberapa efek ke yang lain
class Adaptable subeff eff | subeff -> eff where adapt :: subeff ~> eff
Adaptasi berarti bahwa beberapa efek dapat diganti dengan efek yang lebih kuat. Misalnya, efek
Reader dan
Writer dapat digunakan di
State , karena
State dapat membaca dan menulis, dan dengan demikian mengubah nilai yang disimpan:
lift put :: Accumulated _ t => t _ lift get :: Configured _ t => t _ (lift . adapt $ put) :: Stateful _ t => t _ (lift . adapt $ get) :: Stateful _ t => t _
Bagaimana ini mungkin? Dalam artikel sebelumnya, kami membagi
Negara menjadi dua efek:
State s = (->) s :. (,) s
Dalam kasus
Reader , kami cukup menaikkan functor panah ke tingkat
Negara , dan dalam kasus
Writer , tuple functor:
Reader s = (->) s Writer s = (,) s
Kami dapat menyesuaikan
Failable ke
Opsional , tetapi kami akan kehilangan informasi kesalahan:
(lift $ Just _) :: Optional t => t _ (lift $ failure _) :: Failable _ t => t _ (lift . adapt $ failure _) :: Optional t => t _
Jalankan efek dalam transformer
Untuk menginterpretasikan efek dalam transformator, satu metode
dijalankan sudah cukup:
let xy = x *> y :: Reader _ :> State _ :> Either _ :> Maybe := _ let xy' = run xy _ :: State _ :> Either _ :> Maybe := _ let xy'' = run xy' _ :: Either _ :> Maybe := _ let xy''' = run xy'' :: Maybe (Either _) _
Kesimpulan dan Contoh
Jadi, saat ini, tanpa monad gratis / bebas (dan kadang-kadang bahkan tanpa monad), menggunakan
sambungan Anda dapat mengetik ekspresi Anda sesuai dengan efek yang mereka hasilkan. Yang Anda butuhkan hanyalah komposisi functors.
Ada juga
presentasi dari laporan tentang topik ini di
reli lokal di Rostov-on-Don, yang dapat dilihat di browser.
Contoh terbaik adalah yang sedekat mungkin dengan kenyataan. Saya suka musik, sehingga Anda dapat melihat bagaimana sistem efek ini digunakan dalam
program yang mengunduh album dari Bandcamp .