Saya benar-benar berjuang dengan memahami callCC. Saya mendapatkan kekuatan Kelanjutan dan saya telah menggunakan konsep di beberapa proyek saya untuk membuat konsep keren. Tetapi saya tidak pernah perlu menggunakan sesuatu dengan kemampuan yang lebih besar dari itu cont :: ((a->r)->r)-> Cont r a
.
Setelah menggunakannya, masuk akal mengapa mereka menyebut Cont Monad ibu dari semua monad, BELUM saya tidak mengerti kapan saya harus menggunakannya callCC
, dan itulah pertanyaan saya.
haskell
functional-programming
monads
Alejandro Navas
sumber
sumber
Cont
? Ketika Anda mengatakan Anda tidak perlu menggunakan sesuatu yang lebih kuat dari itucont
, apakah itu berarti Anda belum pernah menggunakanreset
ataushift
keduanya?reset
ataushift
. Saya telah menggunakannya untuk mendefinisikan bahasa eembedded yang dapat ditangguhkan sampai tindakan yang diberikan diselesaikan oleh proses lain, dan kemudian dilanjutkan dengan "kelanjutan" yang diberikan. Mungkin saya memberi kesan memiliki banyak pengalaman dengan Cont Monad, tetapi tidak terlalu banyak, saya hanya benar-benar ingin memahami callCCJawaban:
callCC
memberi Anda semantik "kembali awal", tetapi dalam konteks monadik.Katakanlah Anda ingin
doOne
, dan jika itu kembaliTrue
, Anda segera berhenti, jika tidak Anda pergi kedoTwo
dandoThree
:Lihat
if
cabang itu di sana? Satu cabang tidak seburuk itu, bisa diatasi, tetapi bayangkan ada beberapa titik di mana Anda hanya ingin menebus? Ini menjadi sangat buruk dengan sangat cepat.Dengan
callCC
Anda dapat memiliki "pengembalian awal": Anda membayar pada titik percabangan dan tidak harus membuat sarang dari sisa perhitungan:Jauh lebih menyenangkan untuk dibaca!
Lebih penting lagi, karena di
ret
sini bukan sintaks khusus (sepertireturn
dalam bahasa C-like), tetapi hanya nilai seperti yang lain, Anda dapat meneruskannya ke fungsi lain juga! Dan fungsi-fungsi itu kemudian dapat melakukan apa yang disebut "pengembalian non-lokal" - yaitu mereka dapat "menghentikan"doThings
perhitungan, bahkan dari beberapa panggilan bersarang jauh. Sebagai contoh, saya dapat memfaktorkan pengecekandoOne
hasil ke fungsi terpisahcheckOne
seperti ini:sumber
b
pada dasarnya hanya wildcard sehingga Anda dapat membuat rantai lebih banyak kelanjutan di dalam callCC. Bagaimanapun, setelahret
diterapkan, kelanjutan yang dihasilkan oleh panggilan cc akan "mengembalikan" apa pun yang dimasukkanret
. Itu cukup berbelit-belit, namun cukup pintar, namun sangat kuat. Saya melihat tidak banyak tempat di mana menggunakan kekuatan seperti itu tidak seperti membunuh seekor lalat dengan senjata nuklir