Pertanyaan Apa gunanya 'const' dalam Haskell Prelude?


Melihat melalui Haskell Prelude, saya melihat suatu fungsi  const:

const x _ = x

Saya tidak bisa menemukan sesuatu yang relevan dengan fungsi ini.

Apa gunanya? Adakah yang bisa memberikan contoh di mana fungsi ini mungkin digunakan?


75
2017-09-13 13:17


asal


Jawaban:


Ini berguna untuk beralih ke fungsi tingkat tinggi ketika Anda tidak membutuhkan semua fleksibilitasnya. Misalnya, operator urutan monadik >> dapat didefinisikan dalam hal operator bind monadic sebagai

x >> y = x >>= const y

Ini agak lebih rapi daripada menggunakan lambda

x >> y = x >>= \_ -> y

dan Anda bahkan dapat menggunakannya tanpa titik

(>>) = (. const) . (>>=)

meskipun saya tidak merekomendasikan hal itu dalam kasus ini.


70
2017-09-13 13:20



Untuk menambah jawaban langsung hammar yang bagus: fungsi yang sederhana seperti const dan id benar-benar berguna sebagai fungsi urutan yang lebih tinggi untuk alasan yang sama seperti itu mendasar dalam SKI kalkulus kombinator.

Bukannya saya pikir fungsi pendahuluan haskell dimodelkan secara sadar setelah sistem formal atau apa pun. Hanya saja menciptakan abstraksi yang kaya di haskell sangat mudah, sehingga Anda sering melihat jenis-jenis hal teoretis ini muncul sebagai praktis berguna.

Steker tak tahu malu, tapi saya blog tentang bagaimana contoh Aplikasi untuk (->) sebenarnya adalah S dan K kombinator sini, jika itu adalah hal yang Anda sukai.


24
2017-09-13 14:40



Contoh sederhana untuk digunakan const aku s Data.Functor.(<$). Dengan fungsi ini Anda bisa mengatakan: Saya memiliki fungsi dengan sesuatu yang membosankan di dalamnya, tetapi saya ingin memiliki hal menarik lainnya di dalamnya, tanpa mengubah bentuk functor. Misalnya.

import Data.Functor

42 <$ Just "boring"
--> Just 42

42 <$ Nothing
--> Nothing

"cool" <$ ["nonsense","stupid","uninteresting"]
--> ["cool","cool","cool"]

Definisi ini adalah:

(<$) :: a -> f b -> f a
(<$) =  fmap . const

atau ditulis tidak sebagai gunanya:

cool <$ uncool =  fmap (const cool) uncool

Anda lihat caranya const digunakan di sini untuk "melupakan" tentang input.


21
2017-09-14 08:30



Saya tidak bisa menemukan sesuatu yang relevan dengan fungsi ini.

Banyak dari jawaban lain membahas aplikasi yang relatif esoterik (setidaknya untuk pendatang baru) const. Berikut ini adalah yang sederhana: Anda dapat menggunakannya const untuk menyingkirkan lambda yang mengambil dua argumen, membuang yang pertama tetapi melakukan sesuatu yang menarik dengan yang kedua.

Sebagai contoh, implementasi berikut ini (tidak efisien!) length,

length' = foldr (\_ acc -> 1 + acc) 0

dapat ditulis ulang sebagai

length' = foldr (const (1+)) 0

yang mungkin lebih elegan.

Ekspresi const (1+) memang setara dengan \_ acc -> 1 + acc, karena ia mengambil satu argumen, membuangnya, dan mengembalikan bagian (1+).


14
2018-02-12 20:49



Penggunaan lain adalah untuk mengimplementasikan fungsi anggota kelas yang memiliki argumen dummy yang tidak boleh dievaluasi (digunakan untuk menyelesaikan jenis yang ambigu). Contoh yang bisa ada di Data.bits:

instance Bits Int where
  isSigned = const True
  bitSize  = const wordSize
  ...

Dengan menggunakan const, kita secara eksplisit mengatakan bahwa kita mendefinisikan nilai konstan.

Secara pribadi saya tidak menyukai penggunaan parameter dummy, tetapi jika mereka digunakan di kelas maka ini adalah cara penulisan yang agak bagus.


12
2017-09-14 09:25



const mungkin hanya implementasi yang Anda cari bersama dengan fungsi lain. Inilah contoh yang saya temukan.

Katakanlah kita ingin menulis ulang struktur 2-tupel ke struktur 2-tupel lainnya. Saya mungkin menyatakan ini sebagai berikut:

((a,b),(c,d)) ⇒ (a,(c,(5,a)))

Saya dapat memberikan definisi langsung dengan pencocokan pola:

f ((a,b),(c,d)) = (a,(c,(5,a)))

Bagaimana jika saya menginginkan solusi yang tidak berguna (tacit) untuk penulisan ulang semacam ini? Beberapa berpikir dan mengotak-atik nanti, jawabannya adalah kita dapat mengekspresikan penulisan ulang (&&&), const, (.), fst, snd. Perhatikan itu (&&&) adalah dari Control.Arrow.

Solusi dari contoh menggunakan fungsi-fungsi ini adalah:

(fst.fst &&& (fst.snd &&& (const 5 &&& fst.fst)))

Perhatikan kesamaan dengan (a,(c,(5,a))). Bagaimana jika kita ganti &&& dengan ,? Kemudian itu berbunyi:

(fst.fst, (fst.snd, (const 5, fst.fst)))

Perhatikan caranya a adalah elemen pertama dari elemen pertama, dan itu adalah apa fst.fst proyek. Perhatikan caranya c adalah elemen pertama dari elemen kedua, dan itu adalah apa fst.snd proyek. Artinya, variabel menjadi jalur ke sumbernya.

const memungkinkan kami untuk memperkenalkan konstanta. Menarik bagaimana garis namanya dengan artinya!

Saya kemudian menggeneralisasikan ide ini dengan Applicative sehingga Anda dapat menulis fungsi apa pun dalam gaya tanpa tujuan (selama Anda memiliki analisis kasus yang tersedia sebagai fungsi, seperti maybe, either, bool). Lagi, const memainkan peran memperkenalkan konstanta. Anda dapat melihat ini berfungsi di Data.Function.Tacit paket.

Ketika Anda memulai secara abstrak, pada tujuan, dan kemudian bekerja menuju implementasi, Anda dapat terkejut dengan jawabannya. Artinya, fungsi apa pun mungkin sama misteriusnya dengan salah satu gigi dalam sebuah mesin. Jika Anda menarik kembali untuk menghadirkan seluruh mesin, Anda dapat memahami konteks di mana roda gigi itu diperlukan.


2
2018-06-13 19:21