Alat atau metode resolver parameter jenis generik Haskell [duplikat]

Dec 12 2020

Mari kita lihat jenis fungsi ini misalnya:

:t traverse
traverse
  :: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)

:t id
id :: a -> a

Mereka tidak memiliki jenis beton, tetapi memiliki parameter jenis generik : a, f, b, t(benar kalau mereka disebut tidak jenis parameter generik menyenangkan)

Jika saya menggabungkan iddan traversemenyatu dengan cara ini,

:t traverse id [Just 1, Just 2, Nothing] 
traverse id [Just 1, Just 2, Nothing] :: Num b => Maybe [b]

Haskell sekarang dapat mengikat beberapa jenis beton untuk variabel jenis a, f, b, t.

t = []
a = Maybe bb
f = Maybe
b = Num bb => bb

Di bawah ini saya menyimpulkan jenis dan pemetaan ke parameter dengan tangan, apakah ada cara atau alat di Haskell untuk melakukan ini secara otomatis, sehingga dibutuhkan beberapa bagian yang tersusun ( iddan traverse) dalam sebuah contoh, mengekstrak tanda tangan tipe mereka secara umum, dan pada keluaran yang dihasilkan pemetaan dari nama parameter tipe generik ke tipe kesimpulan konkret?

Lihat juga contoh pertama di sini: https://wiki.haskell.org/Type_inferenceuntuk ekspresi " map ord" tentang cara Haskell menemukan binding dari tipe sebenarnya ke nama.

Jadi ketika kita melihat fungsi secara terpisah kita hanya memiliki nama a, f, b, t. Tapi kemudian kami menggabungkan fungsi dan memberikan beberapa informasi tambahan seperti [Just 1, Just 2, Nothing], dan nama-nama a, f, b, tdipetakan ke jenis beton.

Saya ingin menangkap dan menampilkan pemetaan ini secara otomatis.

Jawaban

Enlico Dec 12 2020 at 00:55

Saya pikir fdan parameter konstruktor tipet yang lebih umum , karena mereka bertindak pada tipe untuk memberi Anda tipe (mereka jenis adalah * -> *, di mana *berarti "tipe konkret").

traverse idtidak komposisi, adalah fungsi aplikasi, seperti Anda melewati idsebagai argumen untuk traverse. this . thatadalah komposisi fungsi antara thisdan that, dalam arti matematis, di mana Anda membuat fungsi yang memberikan argumen (pertama) sebagai masukan thatdan memberi makan hasil aplikasi ini ke this.

Anda mengacu pada contoh di halaman ini , di mana diberikan ini

map :: (a -> b) -> [a] -> [b]
Char.ord :: (Char -> Int)

kompilator dapat menyimpulkan bahwa jenisnya map ordadalah [Char] -> [Int], karena Anda dapat memeriksanya sendiri dengan menulis :t map orddi baris perintah.

Jika Anda mengharapkan keluaran serupa dengan tipe concerete saat Anda mengetik :t traverse id, Anda tidak akan mendapatkannya, karena alasan sederhana itu traverse idmasih merupakan fungsi polimorfik, baik dalam argumen tipe konkretnya maupun argumen konstruktor tipe.

Hanya untuk memberikan contoh yang sedikit berbeda, jika Anda mengetik :t traverse (:[]), where (:[])has type a -> [a], yang merupakan kasus khusus (Applicative f) => a -> f byang traversediharapkan, Anda mendapatkan output ini,

traverse (:[]) :: Traversable t => t b -> [t b]

yang dibandingkan dengan :t traverse,

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

memberi tahu Anda bahwa traverse, dalam traverse (:[]), telah "dipakai" dengan f === []dan a === b.