Saya mencoba mendeklarasikan fungsi di mana argumen numerik hanya bisa berupa Int.

Saya sedang menulis fungsi yang akan membuang setiap nelemen daftar. Saya menggunakan aritmatika modulo, tetapi fungsi mod hanya akan mengambil jenis Int dan saya tidak tahu bagaimana menjamin nomor saya akan memenuhi itu.

Kode saya adalah sebagai berikut:

dropEvery :: (Num n, Eq n) => n -> [a] -> [a]
dropEvery m list = [list !! i | i <- [1 .. length list], i `rem` m /= 0]

Saya telah menjalankan :info mod dan mengganti Num n dengan Real n, Enum n and Integral n (semua kendala yang dapat saya lihat di output) tetapi ini masih tidak menjamin kompiler bahwa n akan sebuah Int.

Saya yakin ada solusi untuk masalah ini yang tidak menggunakan pendekatan imperatif seperti itu, tetapi saya ingin menggunakan kesempatan ini untuk belajar lebih banyak tentang bagaimana tipe dan batasan bekerja di Haskell dengan memecahkan masalah ini secara langsung.

2
Laudosolis 3 April 2019, 15:15

1 menjawab

Jawaban Terbaik

Anda hanya perlu menggunakan tipe aktual Int daripada menggunakan batasan (Num n, Eq n). (Perhatikan bahwa Haskell menggunakan pengindeksan daftar berbasis 0 jadi saya harus menambahkan -1 agar berfungsi dengan benar.)

dropEvery :: Int -> [a] -> [a]
dropEvery m list = [list !! (i-1) | i <- [1 .. length list], i `rem` m /= 0]

main = print $ dropEvery 3 [1..20]

Cobalah secara online!

Jika Anda ingin menghindari !!, Anda juga dapat menghindari pencarian panjang daftar secara eksplisit dengan menggunakan zip yang menggantikan pemahaman daftar Anda dengan

[ l | (l,i) <- zip list [0..], (i+1) `rem` m /= 0]
6
flawr 3 April 2019, 13:06