Saya mengalami masalah estetika kecil dalam proyek musik saya dan itu telah mengganggu saya selama beberapa waktu.
Saya memiliki tipe data Key = C | D | ...
dan saya dapat membangun Scale
dari Key
dan Mode
. Yang Mode
membedakan antara skala mayor dan minor.
Saya dapat mendefinisikan Mode
tipe sebagai fungsi dari Key
hingga Scale
. Dalam hal ini mode akan memiliki nama huruf kecil (yang baik-baik saja) dan saya bisa mendapatkan Skala seperti ini
aScale = major C
Tetapi musisi tidak berbicara seperti ini. Mereka menyebut skala ini sebagai skala C mayor , bukan skala C mayor .
Apa yang saya inginkan
Idealnya saya ingin menulis
aScale = C major
Apakah ini mungkin?
Apa yang saya coba
Saya dapat membuat Key
fungsi yang membangun a Scale
dari Mode
, jadi saya bisa menulis
aScale = c Major
Tapi saya tidak bisa membatasi Kunci untuk membangun Timbangan. Mereka diperlukan untuk hal-hal lain juga (misalnya membangun akord ). Juga Key
harus menjadi contoh dari Show
.
Saya bisa meletakkan Mode
setelah Key
ketika saya menggunakan fungsi tambahan (atau konstruktor nilai):
aScale = scale C major
dengan scale :: Key -> Mode -> Scale
Tetapi skala kata tambahan terlihat berisik dan bertentangan dengan namanya, scale
tidak terlalu peduli dengan skala. Bagian yang cerdas adalah major
, scale
benar-benar adil flip ($)
.
Menggunakan a newtype Mode = Major | Minor ...
tidak terlalu banyak berubah, kecuali scale
harus lebih pintar:
aScale = scale C Major
major C
.Jawaban:
Solusi 1:
Gunakan ini
Sekarang Anda bisa menulis (dengan modal C dan modal M)
Solusi 2a:
Ini juga mungkin
Sekarang kamu menulis
Solusi 2b:
Ini juga mungkin
Sekarang kamu menulis
sumber
Inilah salah satu solusi aneh yang tidak saya rekomendasikan, tetapi terlihat sangat "musikal":
Maka Anda bisa menulis
Tentu saja, di mana ini benar-benar ditujukan adalah bahwa Anda juga akan memiliki
F♯ minor
danB♭ major
lain - lain.sumber
⠀
U + 2800 POLA BRAILLE BLANK dapat digunakan sebagai infiks. Tak perlu dikatakan, ini adalah ide yang mengerikan ... Semua karakter ruang yang sebenarnya dilarang sebagai infiks, tetapi tidak mengejutkan Unicode berisi sesuatu yang dapat diretas ke dalam tujuan penyalahgunaan.Jika Anda tidak keberatan dengan operator tambahan, Anda dapat menggunakan
&
dariData.Function
. Dengan asumsi itumajor
adalah fungsiKey -> Scale
, Anda bisa menulisC & major
. Itu menghasilkanScale
nilai:sumber
Sudah ada beberapa jawaban yang baik, tetapi inilah solusi gaya kelanjutan lewat yang mungkin membantu (mungkin bukan untuk contoh khusus ini, tetapi dalam konteks lain di mana semacam sintaks aplikasi balik diinginkan).
Dengan definisi standar untuk beberapa jenis domain masalah:
Anda dapat memperkenalkan jenis kelanjutan-lewat:
dan tulis tipe-tipe primitif untuk membangun
Cont
tipe-tipe seperti:Kemudian, fungsi pembangunan skala, note, dan chord dapat menyelesaikan
Cont
s ke tipe plain dalam bentuk postfix (yaitu, sebagai kelanjutan yang akan diteruskan keCont
):atau bentuk awalan (yaitu, mengambil
Cont
s sebagai argumen):Sekarang, Anda dapat menulis:
Perhatikan bahwa
c
itu sendiri tidak memilikiShow
instance, tetapic note
tidak.Dengan modifikasi pada
Note
jenisnya, Anda dapat dengan mudah mendukung kecelakaan ganda (mis.c sharp sharp
, Berbeda darid
), dll.sumber
Cont
bagaimanapun, saya mencoba untuk tetap menggunakan konstruktorA | B | C ...
daripada menggunakan fungsi. Saya tidak bisa mendapatkan ini untuk bekerja dan saya masih tidak mengerti mengapa, mengingat bahwa konstruktor nilai hanyalah fungsi. Jika saya dapat menempelkan fungsi di depan Kunci saya, banyak hal menjadi mungkin. Jika fungsinyaflip ($)
maka saya mendapatkan polanyaflip ($) B :: Cont Key r
. Dokumen asli sayaaScale = scale C Major
tidak jauh berbeda.Anda dapat menggunakan kacamata ketik untuk secara cerdik mengatasinya:
Sekarang, Anda juga dapat menggunakan huruf kecil untuk jenis lain dengan mendefinisikan instance yang sesuai.
sumber