Haskell böyük ölçülü dizayn?

Xüsusən Haskelldə böyük funksional proqramların dizaynını / qurulmasının yaxşı bir yolu nədir?

Bir çox dərslik kitabından keçdim (özünü, mənim sevimli kimi, Real World Haskell ilə ikinci ikinci), amma əksər proqramlar nisbətən kiçik və yeganədir. Bundan əlavə, bəzilərinin xüsusilə zərif olduğunu düşünmürəm (məsələn, WYAS-da geniş axtarış masaları).

İndi daha çox hərəkət edən hissələrlə daha geniş proqramları yazmaq istəyirəm - müxtəlif mənbələrdən məlumat almaq, onları təmizləmək, onları müxtəlif yollarla işləmək, istifadəçi interfeyslərində göstərmək, saxlamaq, şəbəkələrlə ünsiyyət qurmaq və s. Bu cür kodu yaxşı oxumaq, dəstəkləmək və dəyişən tələblərə uyğunlaşdırmaq üçün necə qurmaq olar?

Böyük obyektlərə yönəlmiş vacib proqramlar üçün bu məsələlərə həsr olunmuş kifayət qədər geniş ədəbiyyat var. MVC, dizayn nümunələri və s. Kimi fikirlər problem ayırma və OO yenidən istifadə kimi geniş məqsədlərin həyata keçirilməsi üçün layiqli reseptlərdir. Bundan əlavə, yeni imperativ dillər özlərini "bərpa layihəsinə" borc verir, bu da mənim yenilikçi rəyimdə Haskell daha az uyğun görünür.

Haskell üçün bərabər ədəbiyyat varmı? Funksional proqramlaşdırmada (monadlar, oxlar, tətbiqçilər və s.) Ekzotik idarəetmə strukturlarının zooparkından istifadə etmək üçün ən yaxşı yol hansıdır? Hansı tövsiyələrinizi tövsiyə edə bilərsiniz?

Təşəkkür edirik!

EDIT (bu Don Stewartın cavabının davamıdır):

@dons qeyd olunur: "Monadalar növləri üzrə əsas arxitektura dizaynları ələ keçirir."

Mənim sualım belədir: əsas arxitektura layihələri təmiz funksional bir dildə necə düşünmək lazımdır?

Bir neçə məlumat axınının və bir neçə emal addımlarının nümunəsini nəzərdən keçirin. Data axınları üçün bir sıra məlumat strukturlarına modul parserlər yaza bilərik və hər bir emal addımını təmiz bir funksiya kimi tətbiq edə bilərəm. Bir parça məlumat üçün lazım olan emal addımları onun dəyərindən və digərindən asılı olacaq. Bu addımların bəziləri GUI yeniləmələri və ya verilənlər bazası sorguları kimi yan təsirlərlə müşayiət edilməlidir.

Məlumat və analiz addımlarını gözəl bir şəkildə bağlamaq üçün "doğru" yol nədir? Fərqli məlumat növləri üçün doğru olan böyük bir funksiya yaza bilərsiniz. Və ya bu günə qədər işlənmiş işi izləmək üçün monaddan istifadə edə bilərsiniz və hər bir emal qadağası monad dövlətindən lazım olan hər şeyi alır. Yoxsa ayrı-ayrı proqramları yaza və mesaj göndərə bilərsiniz (mən bu variantı sevmirəm).

Onunla əlaqəli olan slaydlar bizdə bir güllə lazım olan bir şey var: "Dizaynın növləri / funksiyalara / siniflərə / monadlərə birləşdirilməsi üçün dəlillər". İddialar nədir? :)

534
20 июня '10 в 4:21 2010-06-20 04:21 Dan 20 İyun tarixində saat 4: 21-da başlayacaq. 2010-06-20 04:21
@ 8 cavab

Haskell'deki Engineering Large Projects və XMonad'ın Dizaynı və İcrasında bu mövzuda bir az danışacağam . Ümumiyyətlə, inkişaf sahəsində idarəetmənin mürəkkəbliyi. Mürəkkəbliyi idarə etmək üçün Haskell kodunun qurulması üçün əsas mexanizmlər aşağıdakılardır:

Sistemi yazın

  • Soyuducular təmin etmək üçün, tip sistemini istifadə edin, birgə çalışmayı asanlaşdırın.
  • Tiplər vasitəsilə əsas invariantlardan istifadə edin
    • (məsələn, müəyyən dəyərlər müəyyən bir sahədən çıxa bilməz)
    • Belirli kodu etməzsə, IO diskə tətbiq edilmir
  • Təhlükəsizlik: yoxlanılmış istisnalar (ehtimal ki), qarışıqlıq anlayışlarından qaçın (Word, Int, Ünvan)
  • Yaxşı məlumat strukturları (ildırım kimi) bəzi test siniflərini lazımsız olaraq edə bilər, məsələn, statik olaraq səhvlərdən kənarda qalırlar.

Profiler

  • Sizin proqram cum və vaxt profillər obyektiv sübut təmin edir.
  • Xüsusilə, yığın profilləri lazımsız yaddaş istifadə təmin etmək üçün ən yaxşı yoldur.

Saflıq

  • Vəziyyəti aradan qaldıraraq mürəkkəbliyi azaltın. Təmiz funksional kod miqyaslıdır, çünki kompozisiya. Lazımdır ki, bir neçə kodun necə istifadə ediləcəyini müəyyən edən bir növüdür - proqramın digər bir hissəsi dəyişdikdə sirrli şəkildə pozulmayacaqdır.
  • Bir çox "model / görünüşü / nəzarətçi" proqramlaşdırma üslubunu istifadə edin: xarici məlumatların mümkün qədər tez işlənmiş məlumat strukturlarında təhlili, bu strukturlar üzərində işləyəcək, sonra isə bütün işləri yerinə yetirməklə, göstərmək / təmizləmək / serializə etmək. Kodu ən çox saxlayır.

Test

  • QuickCheck + Haskell Kod əhatə dairəsi, növlərlə yoxlaya bilməyinizi yoxladığınızdan əmin olmaq üçün.
  • GHC + RTS GC-də çox vaxt sərf etsəniz, görüntü üçün böyükdür.
  • QuickCheck ayrıca modullarınız üçün təmiz ortoqonal API'ləri müəyyən etməyə kömək edə bilər. Kodunuzun xüsusiyyətləri ifadə etmək çətindirsə, ehtimalla çox mürəkkəbdir. Kodunuzu düzgün şəkildə qura bilən təmiz bir xüsusiyyətə malik olana qədər refaktoring saxlayın. Sonra kodu yaxşı hazırlanmışdır.

Monadların qurulması

  • Monadalar əsas tipli memarlıq layihələrini tuturlar (bu kod donanmaya aiddir, bu kod bir istifadəçi seansıdır və s.).
  • məsələn. Xmonad'daki x-monad, bu sistem komponentləri üçün dövlətin göründüyü dizaynı dəqiq şəkildə əks etdirir.

Dərs növləri və mövcud olan növləri

  • Soyutlama təmin etmək üçün tipli dərsləri istifadə edin: tətbiqləri polimorf interfeyslər arxasında saxla.

Eşzamanlılıq və paralellik

  • Müsabiqəni asan, inteqral paralelliklə qazanmaq üçün proqramınıza daxil olun.

Refactor

  • Haskell-i çox təşkil edə bilərsiniz. Tiplər ağıllı şəkildə istifadə edərkən, geniş miqyaslı dəyişikliklərin təhlükəsiz olmasını təmin edir. Bu kod şkalasını artırmağa kömək edəcək. Refactorings tamamlanmadan əvvəl tip səhvlər gətirib çıxaracaq əmin olun.

FFI-dən ağıllı şəkildə istifadə edin

  • FFI xarici kod ilə oynamaq asanlaşdırır, lakin bu xarici kod təhlükəli ola bilər.
  • Qaytarılmış məlumatların forması ilə əlaqədar fərziyyələrə çox diqqətli olun.

Meta proqramlaşdırma

  • Haskell və ya generics bir az bir model çıxarmaq bilər.

Qablaşdırma və paylama

  • Cabal istifadə edin. Öz quruluş sisteminizi çökməyin. (EDIT: Əslində, ehtiyatla başlamaq üçün yığını istifadə etmək istəyirsən.).
  • Yaxşı API sənədləri üçün Haddock istifadə edin.
  • Graphmod kimi alətlər modulunuzun strukturunu göstərə bilər.
  • Haskell Platform kitabxanalarının və alətlərinin versiyalarına etibar edin, əgər mümkünsə. Bu sabit bir əsasdır. (EDIT: Yenə də, bu gün siz stabil istifadəni almaq və istifadəsi üçün istifadə edə bilərsiniz.)

Uyarılar

  • -Wall təmiz saxlamaq üçün istifadə edin. Ayrıca Agda, Isabelle və ya daha çox güvən üçün Catch-ə baxa bilərsiniz. Lint -tipi növünü yoxlamaq üçün təkmilləşdirmələr təklif edən Big hlint-ə baxın.

Bütün bu vasitələrlə, komplekslər arasında mümkün qədər çox qarşılıqlı əlaqələri aradan qaldıraraq, kompleksi saxlaya bilərsiniz. İdeal olaraq, kompozisiya olduğundan qorunması çox asan olan çox böyük bir təmiz kod bazası var. Bu həmişə mümkün deyil, amma buna dəyərdir.

Ümumiyyətlə: sisteminizin məntiqi bölmələrini ən kiçik referans şəffaf komponentlərə ayırın və sonra onları modullarda tətbiq edin. Komponentlərin dəstləri üçün qlobal və ya yerli mühit (və ya daxili komponentlər) monadlarla müqayisə edilə bilər. Əsas məlumat strukturlarını təsvir etmək üçün cəbri məlumat növlərini istifadə edin. Bu tərifləri yaymaq.

496
20 июня '10 в 4:42 2010-06-20 04:42 cavab Don Stewart'a 20 iyun 'da 4:42' də verildi 2010-06-20 04:42

Don sizə yuxarıda ən çox məlumat verdi, amma burada mənim iki sentim var, həqiqətən, Haskelldə sistemin iblisləri kimi, həqiqətən, çox azğın halallıqlı proqramlar edir.

  • Axı, siz bir monad transformator yığını yaşayırsınız. Aşağıda - IO. Bundan əlavə, hər bir əsas modul (özünəməxsus mənada, "faylda modul" mənasında deyil) bu yığındakı bir qatdakı zəruri vəziyyəti göstərir. Buna görə də, bir modulda gizli verilənlər bazası əlaqə kodunuz varsa, bunların hamısını MonadReader Əlaqəsi növü m => ... → m ... üzərinə yazırsınız və sonra verilənlər bazası funksiyaları həmişə funksiyadan funksiyasız istifadə edə bilərlər. digər modullar onun varlığından xəbərdar olmalıdır. Sizə bir verilənlər bazası bağlantısı olan bir qat, bəziləri isə konfiqurasiya, üçdə bir semafor və mvars ilə paralellik və sinxronizasiya, digərinə isə günlük faylınız və s. Daxil ola bilər.

  • İlk səhvinizi işlədiniz. Hal-hazırda Haskell üçün daha böyük sistemlərdə ən böyük zəiflik səhvlərin idarə edilməsi üsullarının çoxluğu, bəlkə də səhv olanlardır (səhv olan, çünki həmişə səhv olan hər hansı bir məlumatı geri ala bilməyəcəksiniz, əvəzinə eksik dəyərlər deməkdir). İlk olaraq bunu necə etdiyini öyrənin və kitabxanalarınızın və digər kodlarınızı sonda istifadə etdiyiniz müxtəlif səhv idarə mexanizmlərindən adapterləri konfiqurasiya edin. Bu, sonradan kədər dünyasını xilas edəcək.

border=0

Əlavə etmək (şərhlərdən çıxarılan, LiiLiminalisht sayəsində) -
yığındakı monadlara böyük bir proqramın kəsilməsinin müxtəlif yolları haqqında daha çox müzakirələr:

Ben Kolera bu mövzuya böyük praktiki giriş təqdim edir və Brian Hurt müntəzəm olaraq monad hərəkətlərini lift üçün həll yollarını müzakirə edir. George Wilson , xüsusi monad görünüşünü deyil, tələb olunan yığın növlərini həyata keçirən hər hansı bir monad ilə işləyən kod yazmaq üçün mtl dan necə istifadə etməyini göstərir. Karlo Hamalainen Corcun sözlərini yazan bəzi qısa, faydalı qeydləri yazdı.

116
21 июня '10 в 13:39 2010-06-21 13:39 cavab 21 iyun 2010- cu il saat 13 : 39 -da user349653 tərəfindən verilmişdir 2010-06-21 13:39

Haskelldə böyük proqramların hazırlanması digər dillərdə bunu etməmişdir. Ümumiyyətlə proqramlaşdırma probleminizi idarə olunan hissələrə və bunları necə birləşdirə bilər; tətbiq dili daha az vacibdir.

Lakin, böyük bir dizaynda, yalnız sizin cihazlarınızı düzgün bir şəkildə uyğunlaşdırdığınızdan əmin olmaq üçün tip sistemini sınamaq və istifadə etmək gözəldir. Bu, növün yeni növünü və ya xəyalını, eyni tipli görünən şeyləri fərqli etmək üçün ola bilər.

Kodun refactoring gəldikdə, irəli getmək zaman, təmizlik böyük bir xeyir, belə ki, kodu mümkün qədər yüksək saxlamağa çalışın. Təmiz kodu, proqramınızın digər hissələri ilə heç bir gizli qarşılıqlı olmadığı üçün yenidən təşkil etmək asandır.

43
20 июня '10 в 12:29 2010-06-20 12:29 Cavab 20 İyun 2013 tarixində saat 12: 29-da verilir. 2010-06-20 12:29

Mən əvvəlcə bu kitabın strukturlaşdırılmış funksional proqramlaşdırmasını öyrəndim. Bəlkə də bu sizin aradığınız şey deyildir, lakin funksional proqramda yeni başlayanlar üçün bu funksional proqramların necə qurulacağını öyrənmək üçün ən yaxşı addımlardan biri ola bilər. Abstraksiya bütün səviyyələrdə dizayn həmişə yaxşı təşkil edilən strukturlara malik olmalıdır.

Funksional proqramlaşdırma yaradılması

2019

15
18 окт. Cavab verildi 18 oct . 2010-10-18 02:23 '10 saat 02:23 'da 2010-10-18 02:23

Hal-hazırda funksional dizayn və arxitektura adlı bir kitab yazıram. Bu, təmiz bir funksional yanaşma istifadə edərək, böyük bir proqram qurmaq üçün bir sıra üsullarla təmin edir. Kosmik aparatı sıfırdan idarə etmək üçün SCADA kimi "Andromeda" tətbiqini yaratarkən çox funksional modelləri və ideyaları təsvir edir. Mənim əsas dilim Haskelldir. Kitab əhatə edir:

  • Diaqramlardan istifadə edərək memarlıq modelləşdirilməsinə dair yanaşmalar;
  • Tələblərin təhlili;
  • Daxili DSL domain modelləşdirmə;
  • DSL-nin xarici dizaynı və tətbiqi;
  • Effektləri olan alt sistemlər kimi monadlar;
  • Funksional interfeys kimi pulsuz monadlar;
  • EdsL vurmaq;
  • Pulsuz monadic eDSL istifadə edərək nəzarət ters çevirmək;
  • Proqram əməliyyat yaddaş;
  • linzalar;
  • Dövlət, Reader, Writer, RWS, ST monads;
  • Arıq dövlət: IORef, MVar, STM;
  • Multi-yivli və paralel domain modelləşdirilməsi;
  • qrafik interfeys;
  • UML, SOLID, GRASP kimi əsas üsul və yanaşmaların tətbiq olunması;
  • Nasos alt sistemləri ilə qarşılıqlı əlaqə.

Kitabın kodu və "Andromeda" nın kodunu oxuya bilərsiniz.

Bu kitabı 2017-ci ilin sonunda bitirməyi planlaşdırıram. Bu baş verənədək, burada "Dizayn və Mimari funksional proqramlaşdırma" (Rus) məqaləsini oxuya bilərsiniz .

ƏLAVƏ OLUNUB

Kitabımı internetdə paylaşdım (ilk 5 fəsildən). Redditdə posta baxın

11
20 нояб. Cavab 20 noyabr tarixində GAZ tərəfindən verilir. 2016-11-20 08:25 '16 saat 8:25 'də 2016-11-20 08:25' də

Gabriel blog yazısı Ölçeklenebilir proqram mimarileri söz edilə bilər.

Haskell dizayn nümunələri bir şeydə əsas dizayn nümunələrindən fərqlənir:

  • Ənənəvi memarlıq . Bir neçə komponenti birlikdə birləşdirin. B tipli "şəbəkə" və ya "topoloji" yaratmaq üçün A yazın

  • Haskell arxitekturası : bir neçə növ A komponenti birləşir, eyni tipli A komponenti yaradır, onun əvəz hissələrindən bir simvol olaraq fərqləndirilmir

Tez-tez mənə elə gəlir ki, zərif arxitektura tez-tez bu xoşagəlməz homojenlik hissi göstərən kitabxanalardan çıxır, yuxarıdan. Haskelldə bu, xüsusilə də aydındır - ənənəvi olaraq "yuxarıdan aşağıya düşən" memarlıq nümunələri mvc , netwireCloud Haskell kimi kitabxanalarda müəyyən edilir. Yəni ümid edirəm ki, bu cavab bu axındakı hər hansı birinin əvəz edilməsinə cəhd kimi şərh edilməyəcəkdir, yalnız struktur seçimi və ideal olaraq kütləvi kitabxanalara domen ekspertləri tərəfindən cəlb edilməlidir. Böyük sistemlərin qurulması əsl çətinlik, mənim fikrimcə, bu kitabxanaların bütün praktik problemlərinizlə müqayisədə onların memarlıq "xeyirxahlığı" ilə qiymətləndirir.

Şikayətdə qeyd olunduğu kimi, şablon dizayn kateqoriyası Gabriel tərəfindən bu mövzu ilə eyni vəzifədədir.

7
31 авг. Rehno Lindeque tərəfindən verilmiş cavab 31 Avqust. 2014-08-31 13:07 '14 at 13:07 2014-08-31 13:07

Mən Haskellin geniş diametrli strukturu barədə düşünmək üçün faydalı olan Alejandro Serrano tərəfindən "Haskell istifadə edərək proqram təminatı memarlığının tədrisi" (pdf) məqaləsini tapdım.

4
18 февр. Cavab 18 fevral tarixində haroldcarr tərəfindən verilir . 2016-02-18 22:24 '16 saat 10: 24-da 2016-02-18 22:24

Bəlkə bir addım geri çəkilmək və problemin təsviri dizaynına əvvəlcədən necə keçməyi düşünmək lazımdır. Haskell çox yüksək olduğundan, problem strukturları, məlumat strukturları, əməliyyatlar kimi əməliyyatlar və funksiyalar kimi təmiz transformasiya şəklində göstərə bilər. Sonra bir dizaynınız var. İnkişaf, bu kodu tərtib edərkən və eksik sahələr, eksik nümunələr və kodu içərisində monadçı transformatorların çatışmamazlığı ilə əlaqədar xüsusi səhvlər tapmaqda başlayır, çünki, məsələn, giriş prosedurunda müəyyən bir vəziyyətə ehtiyacı olan bir kitabxanadan bazaya daxil olursunuz. çıxdı. Və voila, bir proqram var. Derivor sizin əqli eskizlərinizi qidalandırır və dizayn və inkişafa uyğun gəlir.

Beləliklə, başlanğıcdan Haskell istifadə və kodlaşdırma təbiidir. Əgər nəzərə alsaq, adi bir problemdirsə, mən "funksional" və ya "təmiz" bir şey etmək istəməzdim. Hesab edirəm ki, həddindən artıq mühəndislik İT-də ən təhlükəli şeydir. Başqa bir məsələ, problem bir sıra problemləri özündə əks etdirən kitabxana yaratmaqdır.

2
30 апр. Agocorona tərəfindən verilmiş cavab 30 apreldə 2013-04-30 11:50 '13 'da 11:50' də 2013-04-30 11:50