Haskell hakkındaki yaygara nedir? [kapalı]


109

Aralarındayken Haskell hakkında konuşmaya devam eden birkaç programcı tanıyorum ve burada SO'da herkes bu dili seviyor gibi görünüyor. Haskell'de iyi olmak bir şekilde dahi bir programcının ayırt edici özelliği gibi görünüyor.

Birisi neden bu kadar zarif / üstün olduğunu gösteren birkaç Haskell örneği verebilir mi?

Yanıtlar:


134

Bana sunulma şekli ve Haskell üzerinde bir aydır öğrenmeye çalıştıktan sonra doğru olduğunu düşündüğüm şey, fonksiyonel programlamanın beyninizi ilginç şekillerde çarpıtması: sizi tanıdık problemler hakkında farklı şekillerde düşünmeye zorluyor. : Döngüler yerine, haritalar, kıvrımlar ve filtreler vb. üzerinde düşünün. Genel olarak, bir soruna birden fazla bakış açınız varsa, bu sorun hakkında daha iyi mantık yürütmenizi ve gerektiğinde bakış açılarını değiştirmenizi sağlar.

Haskell ile ilgili gerçekten güzel olan diğer şey, yazı sistemidir. Kesinlikle yazılmıştır, ancak tür çıkarım motoru, aptalca bir türle ilgili hata yaptığınızda size sihirli bir şekilde söyleyen bir Python programı gibi hissettirir. Haskell'in bu konudaki hata mesajları bir şekilde eksiktir, ancak dili daha iyi tanıdıkça kendinize söyleyeceksiniz: yazmanın olması gereken şey budur!


47
Haskell'in hata mesajlarının eksik olmadığı, ghc'lerin eksik olduğu unutulmamalıdır. Haskell standardı, hata mesajlarının nasıl yapıldığını belirtmez.
PyRulez

Benim gibi plebler için GHC, Glasgow Haskell Compiler'ın kısaltmasıdır. en.wikipedia.org/wiki/Glasgow_Haskell_Compiler
Lorem Ipsum

137

Bu beni Haskell'i öğrenmeye ikna eden örnek (ve oğlum öğrendiğime memnunum).

-- program to copy a file --
import System.Environment

main = do
         --read command-line arguments
         [file1, file2] <- getArgs

         --copy file contents
         str <- readFile file1
         writeFile file2 str

Tamam, bu kısa, okunabilir bir program. Bu anlamda bir C programından daha iyidir. Fakat bunun, çok benzer bir yapıya sahip bir Python programından (diyelim ki) farkı nedir?

Cevap tembel bir değerlendirmedir. Çoğu dilde (hatta bazı işlevsel olanlarda), yukarıdaki gibi yapılandırılmış bir program, tüm dosyanın belleğe yüklenmesine ve ardından yeni bir adla yeniden yazılmasına neden olur.

Haskell "tembeldir". Bir şeyleri ihtiyacı olana kadar hesaplamaz ve dolayısıyla asla ihtiyaç duymadığı şeyleri hesaplamaz. Örneğin, writeFilesatırı kaldırırsanız , Haskell ilk başta dosyadan herhangi bir şey okumakla uğraşmazdı.

Olduğu gibi, Haskell bu veri yolunu optimize edebiliyor ve buna writeFilebağlı olduğunu fark ediyor readFile.

Sonuçlar derleyiciye bağlı olsa da, yukarıdaki programı çalıştırdığınızda tipik olarak şudur: program ilk dosyanın bir bloğunu (diyelim ki 8KB), ardından ikinci dosyaya yazar, ardından ilkinden başka bir bloğu okur. dosya ve ikinci dosyaya yazar vb. ( straceÜzerinde koşmayı deneyin !)

... bu, bir dosya kopyasının verimli C uygulamasının yapacağı şeye çok benziyor.

Dolayısıyla Haskell, genellikle çok fazla performanstan ödün vermeden kompakt, okunabilir programlar yazmanıza izin verir.

Eklemem gereken başka bir şey de Haskell'in hatalı programlar yazmayı zorlaştırmasıdır. Şaşırtıcı tip sistemi, yan etkilerin olmaması ve elbette Haskell kodunun kompaktlığı, en az üç nedenden dolayı hataları azaltır:

  1. Daha iyi program tasarımı. Azaltılmış karmaşıklık, daha az mantık hatasına yol açar.

  2. Kompakt kod. Hataların var olması için daha az satır.

  3. Hataları derleyin. Pek çok böcek sadece geçerli Haskell değil .

Haskell herkes için değil. Ama herkes denemeli.


8KB sabitini (veya her ne ise) tam olarak nasıl değiştirirsiniz? Çünkü bir Haskell uygulamasının bir C sürümünden daha yavaş olacağına bahse girerim, özellikle de önceden getirmeden ...
user541686

1
@Mehrdad ile tampon boyutunu değiştirebilirsiniz hSetBuffering handle (BlockBuffering (Just bufferSize)).
David

3
Bu cevabın 116 olumlu oyu olması şaşırtıcı ama içeride ne var ki yanlış. Bu program olacak tembel Bytestrings (siz ile yapabileceğiniz kullanmadıkça, dosyanın tamamını okumak Data.Bytestring.Lazy.readFileHaskell tembel (non-sıkı) dili olmakla hiçbir ilgisi yoktur). Monads olan sıralama bu araçlar kabaca "Eğer sonuç almak zaman tüm yan etkiler yapılır." - "Tembel Bytestring" büyüsüne gelince: bu tehlikelidir ve bunu diğer dillerin çoğunda benzer veya daha basit sözdizimi ile yapabilirsiniz.
Jo So

14
Sıkıcı eski standart readFileda aynı şekilde tembel IO Data.ByteString.Lazy.readFileyapar. Yani cevap yanlış değil ve sadece bir derleyici optimizasyonu değil. Aslında, bu Haskell spesifikasyonunun bir parçasıdır : " readFileİşlev bir dosyayı okur ve dosyanın içeriğini bir dize olarak döndürür. Dosya, istendiğinde, istendiğinde tembel olarak okunur getContents."
Daniel Wagner

1
Bence diğer cevaplar Haskell hakkında daha özel olan şeylere işaret ediyor. Birçok dil / ortamlar size Düğüm benzer şeyler yapabiliriz, akışları vardır: const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2)). Bash'de de benzer bir şey var:cat $1 > $2
Max Heiber

64

Yanlış soruyu soruyorsunuz.

Haskell birkaç serin örneklere göz gidip gidip bir dil değil "aha, şimdi bakın, var iyi kılan!"

Daha çok, tüm bu diğer programlama dillerine sahibiz ve hepsi aşağı yukarı birbirine benziyor ve sonra, çılgınlığa alıştığınızda tamamen harika bir şekilde tamamen farklı ve tuhaf olan Haskell var. Ama sorun şu ki, çılgınlığa alışmak epey zaman alıyor. Haskell'i neredeyse tüm diğer yarı ana akım dillerden ayıran şeyler:

  • Tembel değerlendirme
  • Yan etki yok (her şey saf, IO / vb. Monadlar aracılığıyla oluyor)
  • İnanılmaz derecede etkileyici statik tip sistem

ve birçok ana dilden farklı olan (ancak bazıları tarafından paylaşılan) diğer bazı yönler:

  • fonksiyonel
  • önemli boşluk
  • tür türetilmiş

Diğer bazı posterlerin yanıtladığı gibi, tüm bu özelliklerin birleşimi, programlama hakkında tamamen farklı bir şekilde düşündüğünüz anlamına gelir. Ve bu yüzden bunu Joe-ana-programcıya yeterince iletecek bir örnek (veya bir dizi örnek) bulmak zor. Bu deneyimsel bir şey. (Bir benzetme yapmak gerekirse, Çin'e yaptığım 1970 seyahatinin fotoğraflarını size gösterebilirim, ancak fotoğrafları gördükten sonra, o dönemde orada yaşamış olmanın nasıl bir şey olduğunu hala bilmeyeceksiniz. Benzer şekilde, size bir Haskell de gösterebilirim 'hızlı sıralama', ancak yine de Haskeller olmanın ne anlama geldiğini bilemeyeceksiniz.)


17
İlk cümlenize katılmıyorum. Başlangıçta Haskell kodunun birkaç örneğinden çok etkilendim ve beni gerçekten öğrenmeye değer olduğuna ikna eden şey şu makaleydi : cs.dartmouth.edu/~doug/powser.html Ama elbette bu bir matematikçi / fizikçi için ilginç. Gerçek dünyayla ilgili şeylere bakan bir programcı bu örneği gülünç bulacaktır.
Rafael S. Calsaverini

2
@Rafael: Bu, "gerçek dünyadaki şeylere bakan bir programcı neyden etkilenir" sorusunu akla getiriyor?
JD

İyi soru! Ben "gerçek dünya" programcısı değilim, bu yüzden ne sevdiklerini bilmiyorum. hahaha ... Fizikçilerin ve matematikçilerin neyi sevdiğini biliyorum. : P
Rafael S. Calsaverini

27

Haskell'i gerçekten ayıran şey, tasarımında fonksiyonel programlamayı uygulamak için harcadığı çabadır. Hemen hemen her dilde işlevsel bir tarzda programlayabilirsiniz, ancak ilk rahatlıkla terk etmek çok kolaydır. Haskell, işlevsel programlamayı terk etmenize izin vermez, bu yüzden onu mantıksal sonucuna götürmelisiniz, bu da akıl yürütmesi daha kolay olan ve en dikenli böcek türlerinin tüm sınıfından kaçan son bir programdır.

Gerçek dünyada kullanım için bir program yazmak söz konusu olduğunda, Haskell'in bazı pratik şekillerde eksik olduğunu fark edebilirsiniz, ancak nihai çözümünüz, Haskell'i tanımanız için daha iyi olacaktır. Kesinlikle henüz orada değilim, ancak şu ana kadar Haskell'i öğrenmek, Lisp üniversitede olduğunu söylemekten çok daha aydınlatıcı oldu.


1
Her zaman ve sadece ST monadını kullanma ve / veya unsafePerformIOsadece dünyanın yanışını izlemek isteyenler için her zaman bir olasılık vardır ;)
sara

22

Yaygaranın bir kısmı, saflığın ve statik yazmanın agresif optimizasyonlarla birlikte paralelliği mümkün kılmasıdır. Paralel diller artık çok çekirdekli ve biraz rahatsız edici.

Haskell, hızlı, yerel bir kod derleyicinin yanı sıra hemen hemen tüm genel amaçlı dillerden daha fazla paralellik seçeneği sunar. Paralel stiller için bu tür bir destekle gerçekten rekabet yok:

Dolayısıyla, çok çekirdekli çalışmanızı önemsiyorsanız, Haskell'in söyleyecek bir şeyi vardır. Simon Peyton Jones'un Haskell'de paralel ve eşzamanlı programlama üzerine öğreticisi başlamak için harika bir yerdir .


"hızlı, yerel bir kod derleyicisi ile birlikte"?
JD

Dons'un GHCI'dan bahsettiğine inanıyorum.
Gregory Higley

3
@Jon: shootout.alioth.debian.org/u32/… Haskell, örneğin çatışmada oldukça başarılı.
Peaker

4
@Jon: Shootout kodu çok eski ve GHC'nin daha az optimize edici bir derleyici olduğu uzak bir geçmişten. Yine de, Haskell kod kanıtlıyor olabilir gerekirse, performans vermesi için düşük seviyeli gidin. Çatışmadaki yeni çözümler daha deyimsel ve hala hızlı.
Peaker

1
@GregoryHigley GHCI ve GHC arasında bir fark var.
Jeremy List

18

Yazılım İşlem Belleği , eşzamanlılıkla başa çıkmanın oldukça güzel bir yoludur. Mesaj iletmekten çok daha esnektir ve muteksler gibi kilitlenme eğilimli değildir. GHC'nin STM uygulaması en iyilerden biri olarak kabul edilir.


18

Geçen yılı Haskell öğrenerek ve içinde oldukça büyük ve karmaşık bir proje yazarak geçirdim. (Proje, otomatikleştirilmiş bir opsiyon ticaret sistemidir ve ticaret algoritmalarından düşük seviyeli, yüksek hızlı piyasa veri akışlarının ayrıştırılmasına ve işlenmesine kadar her şey Haskell'de yapılır.) Çok daha kısa ve anlaşılması daha kolaydır ( uygun arka plan) bir Java sürümünden daha güçlü ve oldukça sağlamdır.

Muhtemelen benim için en büyük kazanç, monoidler, monadlar vb. Şeyler aracılığıyla kontrol akışını modülerleştirme yeteneğiydi. Çok basit bir örnek, Ordering monoid olabilir; gibi bir ifadede

c1 `mappend` c2 `mappend` c3

burada c1ve böylece dönüş LT, EQya da GT, c1geri EQnedenlerini ifade değerlendirmek, devam etmek için c2; eğer c2döner LTveya GTbu bütün değeridir ve c3değerlendirilmez. Bu tür şeyler, monadik mesaj üreteçleri ve ayrıştırıcılar gibi farklı durum türlerini taşıyabileceğim, değişen durdurma koşullarına sahip olabileceğim veya iptalin gerçekten ne anlama geldiğine dair herhangi bir özel çağrı için karar verebilmek isteyebileceğim şeylerde önemli ölçüde daha karmaşık ve karmaşık hale geliyor. "daha fazla işlem yok" veya "sonunda bir hata döndürür, ancak daha fazla hata mesajı toplamak için işleme devam edin" anlamına gelir.

Bunların hepsi biraz zaman ve muhtemelen öğrenmesi epey çaba gerektiren şeylerdir ve bu nedenle, bu teknikleri bilmeyenler için ikna edici bir argüman yapmak zor olabilir. Monads Hakkında Her Şey öğreticisinin bunun bir yönünün oldukça etkileyici bir gösterimini sunduğunu düşünüyorum , ancak materyale aşina olmayan hiç kimsenin ilkinde, hatta üçüncü dikkatli okumada onu zaten " anlayacağını" beklemiyorum.

Her neyse, Haskell'de başka pek çok güzel şey de var, ama bu çok sık bahsetmediğim bir şey, muhtemelen oldukça karmaşık olduğu için.


2
Çok ilginç! Otomatik ticaret sisteminize toplamda kaç satır Haskell kodu girdi? Hata toleransını nasıl başardınız ve ne tür performans sonuçları elde ettiniz? Son zamanlarda Haskell'in düşük gecikmeli programlama için iyi olma potansiyeline sahip olduğunu düşünüyordum ...
JD

12

İlginç bir örnek için şu adrese bakabilirsiniz: http://en.literateprograms.org/Quicksort_(Haskell)

İlginç olan, uygulamaya çeşitli dillerde bakmaktır.

Haskell'i diğer işlevsel dillerle birlikte bu kadar ilginç kılan şey, nasıl programlanacağı konusunda farklı düşünmeniz gerektiği gerçeğidir. Örneğin, genellikle for veya while döngülerini kullanmayacaksınız, ancak özyinelemeyi kullanacaksınız.

Yukarıda belirtildiği gibi, Haskell ve diğer işlevsel diller, çoklu çekirdekler üzerinde çalışmak için paralel işleme ve yazma uygulamalarıyla mükemmeldir.


2
özyineleme bombadır. bu ve desen eşleştirme.
Ellery Newcomer

1
İşlevsel bir dilde yazarken döngülerden kurtulmak benim için en zor kısımdır. :)
James Black

4
Döngüler yerine özyinelemeli düşünmeyi öğrenmek benim için de en zor kısımdı. Nihayet ortaya çıktığında, şimdiye kadar sahip olduğum en büyük programlama epifanilerinden biriydi.
Chris Connett

8
Çalışan Haskell programcısının nadiren ilkel özyineleme kullanması dışında; çoğunlukla map ve foldr gibi kütüphane işlevlerini kullanıyorsunuz.
Paul Johnson

18
Hoare'nin orijinal hızlı sıralama algoritmasının, görünüşte bu yer dışı liste tabanlı biçime alçaltılmış olması ve böylelikle faydasız bir şekilde verimsiz uygulamaların Haskell'de "zarif" bir şekilde yazılabilmesini daha ilginç buluyorum. Haskell'de gerçek bir (yerinde) hızlı sıralama yazmaya çalışırsanız, cehennem kadar çirkin olduğunu göreceksiniz. Haskell'de rekabetçi performans gösteren genel bir hızlı sıralama yazmaya çalışırsanız, GHC'nin çöp toplayıcısındaki uzun süredir devam eden hatalar nedeniyle bunun gerçekten imkansız olduğunu göreceksiniz. Haskell'in dilenci inancı IMHO için iyi bir örnek olarak selamlamak.
JD

8

Size bir örnek veremedim, ben bir OCaml adamıyım, ama ben kendim gibi bir durumdayken, merak uyandırıyor ve bir derleyici / tercüman indirip denemem gerekiyor. Belirli bir işlevsel dilin güçlü ve zayıf yönleri hakkında muhtemelen çok daha fazlasını öğreneceksiniz.


1
Derleyicinin kaynak kodunu okumayı unutmayın. Bu aynı zamanda size birçok değerli bilgi verecektir.
JD

7

Algoritmalar veya matematiksel problemlerle uğraşırken çok havalı bulduğum bir şey, Haskell'in hesaplamaların doğasında olan tembel değerlendirmesidir ve bu, yalnızca katı işlevsel doğası nedeniyle mümkündür.

Örneğin, tüm asal sayıları hesaplamak istiyorsanız, şunu kullanabilirsiniz:

primes = sieve [2..]
    where sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0]

ve sonuç aslında sonsuz bir listedir. Ancak Haskell onu sağdan soldan değerlendirecektir, bu nedenle tüm listeyi gerektiren bir şey yapmaya çalışmadığınız sürece, program sonsuza takılmadan da kullanabilirsiniz, örneğin:

foo = sum $ takeWhile (<100) primes

100'den az olan tüm asal sayıları toplar. Bu birkaç nedenden dolayı güzeldir. Her şeyden önce, tüm asal sayıları üreten tek bir asal fonksiyon yazmam gerekiyor ve sonra asallarla çalışmaya hemen hemen hazırım. Nesne yönelimli bir programlama dilinde, işleve dönmeden önce kaç asal hesaplaması gerektiğini söylemenin veya bir nesneyle sonsuz liste davranışını taklit etmenin bir yolunu bulmalıyım. Başka bir şey de, genel olarak, neyi hesaplamak istediğinizi ifade eden ve bir şeyleri hangi sırayla değerlendirmek yerine ifade eden bir kod yazmanızdır - onun yerine derleyici bunu sizin için yapar.

Bu sadece sonsuz listeler için kullanışlı değildir, aslında gereğinden fazla değerlendirmeye gerek olmadığı zaman siz bilmeden de kullanılır.


2
Bu tamamen doğru değil; C # (bir nesne yönelimli dil) getiri getiri davranışıyla, talep üzerine değerlendirilen sonsuz listeleri de bildirebilirsiniz.
Jeff Yates

2
İyi bir nokta. Haklısınız ve diğer dillerde neyin bu kadar kategorik olarak yapılabileceğini ve yapılamayacağını belirtmekten kaçınmalıyım. Örneğimin kusurlu olduğunu düşünüyorum, ancak yine de Haskell'in tembel değerlendirme yönteminden bir şeyler elde ettiğinizi düşünüyorum: varsayılan olarak ve programcının herhangi bir çabası olmadan gerçekten oradadır. Ve bunun, işlevsel doğası ve yan etkilerinin olmamasından kaynaklandığına inanıyorum.
waxwing

8
"Elek" in neden Eratosthenes'in Kalburu olmadığını okumak ilginizi çekebilir : lambda-the-ultimate.org/node/3127
Chris Conway

@Chris: Teşekkürler, aslında oldukça ilginç bir makaleydi! Yukarıdaki asal işlevi, acı verici bir şekilde yavaş olduğu için kendi hesaplamalarım için kullandığım işlev değil. Bununla birlikte, makale mod için tüm sayıları kontrol etmenin gerçekten farklı bir algoritma olduğu konusunda iyi bir noktayı ortaya koyuyor.
04'te ağda

6

Birkaç küçük örnek görmenin Haskell'i göstermenin en iyi yolu olmadığı konusunda başkalarına katılıyorum. Ama yine de biraz vereceğim. İşte sizden bir üçgenin tabanından tepesine maksimum toplam yolu bulmanızı isteyen Euler Projesi 18 ve 67 problemleri için yıldırım hızında bir çözüm :

bottomUp :: (Ord a, Num a) => [[a]] -> a
bottomUp = head . bu
  where bu [bottom]     = bottom
        bu (row : base) = merge row $ bu base
        merge [] [_] = []
        merge (x:xs) (y1:y2:ys) = x + max y1 y2 : merge xs (y2:ys)

İşte Lesh ve Mitzenmacher tarafından BubbleSearch algoritmasının eksiksiz, yeniden kullanılabilir bir uygulaması . DVD'de arşiv depolamak için büyük medya dosyalarını atık olmadan paketlemek için kullandım:

data BubbleResult i o = BubbleResult { bestResult :: o
                                     , result :: o
                                     , leftoverRandoms :: [Double]
                                     }
bubbleSearch :: (Ord result) =>
                ([a] -> result) ->       -- greedy search algorithm
                Double ->                -- probability
                [a] ->                   -- list of items to be searched
                [Double] ->              -- list of random numbers
                [BubbleResult a result]  -- monotone list of results
bubbleSearch search p startOrder rs = bubble startOrder rs
    where bubble order rs = BubbleResult answer answer rs : walk tries
            where answer = search order
                  tries  = perturbations p order rs
                  walk ((order, rs) : rest) =
                      if result > answer then bubble order rs
                      else BubbleResult answer result rs : walk rest
                    where result = search order

perturbations :: Double -> [a] -> [Double] -> [([a], [Double])]
perturbations p xs rs = xr' : perturbations p xs (snd xr')
    where xr' = perturb xs rs
          perturb :: [a] -> [Double] -> ([a], [Double])
          perturb xs rs = shift_all p [] xs rs

shift_all p new' [] rs = (reverse new', rs)
shift_all p new' old rs = shift_one new' old rs (shift_all p)
  where shift_one :: [a] -> [a] -> [Double] -> ([a]->[a]->[Double]->b) -> b
        shift_one new' xs rs k = shift new' [] xs rs
          where shift new' prev' [x] rs = k (x:new') (reverse prev') rs
                shift new' prev' (x:xs) (r:rs) 
                    | r <= p    = k (x:new') (prev' `revApp` xs) rs
                    | otherwise = shift new' (x:prev') xs rs
                revApp xs ys = foldl (flip (:)) ys xs

Eminim bu kod rastgele anlamsız görünmektedir. Ancak Mitzenmacher'ın blog girişini okursanız ve algoritmayı anlarsanız , aradığınız şey hakkında hiçbir şey söylemeden algoritmayı koda paketlemenin mümkün olduğuna şaşıracaksınız.

Size istediğiniz gibi bazı örnekler verdikten sonra şunu söyleyeceğim: Haskell'i takdir etmeye başlamanın iyi yolunun , bana DVD paketleyiciyi yazmak için ihtiyacım olan fikirleri veren makaleyi okumak olduğunu söyleyeceğim: John Hughes'un yazdığı Why Functional Programming Matters . Makale aslında Haskell'den öncesine dayanıyor, ancak insanları Haskell'i sevdiren bazı fikirleri parlak bir şekilde açıklıyor.


5

Benim için Haskell'in cazibesi, derleyicinin garantili doğruluk vaadidir . Kodun saf kısımları için olsa bile.

Ben bilimsel simülasyon kod çok yazdım ve merak etmiş , böylece cari bir sürü iş geçersiz hale getirebilir benim önceki kodlarında bir hata, varsa birçok kez.


6
Doğruluğu nasıl garanti eder?
Jonathan Fischoff

Kodun saf kısımları, saf olmayanlardan çok daha güvenlidir. Yatırım yapılan güven / çaba düzeyi çok daha yüksektir.
rpg

1
Sana bu izlenimi ne verdi?
JD

5

Haskell ile bazı görevler için inanılmaz derecede üretken olduğumu görüyorum.

Nedeni, kısa sözdizimi ve test etme kolaylığı nedeniyledir.

İşlev bildirimi sözdizimi şuna benzer:

foo a = a + 5

Bu, bir işlevi tanımlamanın en basit yolu.

Tersini yazarsam

inverseFoo a = a - 5

Herhangi bir rastgele girdinin tersi olup olmadığını yazarak kontrol edebilirim

prop_IsInverse :: Double -> Bool
prop_IsInverse a = a == (inverseFoo $ foo a)

Ve komut satırından arıyorum

jonny @ ubuntu: runhaskell quickCheck + isimleri fooFileName.hs

Bu, girdileri yüzlerce kez rastgele test ederek dosyamdaki tüm özelliklerin tutulduğunu kontrol edecek.

Haskell'in her şey için mükemmel bir dil olduğunu sanmıyorum, ancak konu küçük işlevler yazmak ve test etmek olduğunda, bundan daha iyisini görmedim. Programlamanızın matematiksel bir bileşeni varsa, bu çok önemlidir.


Hangi sorunları çözüyorsunuz ve başka hangi dilleri denediniz?
JD

1
Cep telefonu ve iPad için gerçek zamanlı 3B grafikler.
Jonathan Fischoff

3

Haskell'deki yazı sistemine kafanızı sarabilirseniz, bunun başlı başına bir başarı olduğunu düşünüyorum.


1
Elde edilecek ne var? Gerekirse, "data" == "class" ve "typeclass" = "interface" / "role" / "trait" gibi konuları düşünün. Daha basit olamazdı. (Sizi karıştıracak "boş" bile yoktur. Null, kendi türünüze kendiniz yerleştirebileceğiniz bir kavramdır.)
jrockway

8
Alınacak çok şey var, jrockway. Siz ve ben bunu nispeten basit bulurken, birçok insan - hatta birçok geliştirici - belirli türden soyutlamaları anlamak çok zor. Her gün kullansalar bile, daha yaygın dillerdeki işaretçiler ve referanslar fikrini hala tam olarak kavramayan birçok geliştirici tanıyorum.
Gregory Higley

2

döngü yapıları yoktur. pek çok dilde bu özellik yoktur.


17
ghci>: m + Control.Monad ghci> forM_ [1..3] yazdır 1 2 3
sastanin

1

Fonksiyonel programlamanın beyninizi programlamayı farklı bir açıdan görmeye yönlendirdiğini söyleyenlere katılıyorum. Bunu sadece bir hobi olarak kullandım, ancak bir soruna yaklaşımımı temelden değiştirdiğini düşünüyorum. Haskell'e maruz kalmadan (ve Python'da oluşturucular ve liste anlamalarını kullanmadan) LINQ ile neredeyse bu kadar etkili olacağımı sanmıyorum.


-1

Aykırı bir görüş ortaya koymak için : Steve Yegge Hindely-Milner dillerinin iyi sistemler yazmak için gereken esnekliğe sahip olmadığını yazıyor :

HM tamamen işe yaramaz biçimsel matematiksel anlamda çok güzel. Birkaç hesaplama yapısını çok iyi işler; Haskell, SML ve OCaml'de bulunan desen eşleştirme gönderimi özellikle kullanışlıdır. Şaşırtıcı olmayan bir şekilde, diğer bazı yaygın ve oldukça arzu edilen yapıları en iyi ihtimalle garip bir şekilde ele alıyor, ancak bu senaryoları yanıldığınızı, aslında onları istemediğinizi söyleyerek açıklıyorlar. Değişkenleri ayarlamak gibi şeyler.

Haskell öğrenmeye değer, ancak kendi zayıf yönleri de var.


5
Güçlü tip sistemlerin genellikle onlara bağlı kalmanızı gerektirdiği kesinlikle doğru olsa da (güçlerini faydalı kılan budur), aynı zamanda mevcut HM tabanlı sistemlerin birçoğunun (çoğu?) Aslında bir tür ' bağlantıda açıklandığı gibi kaçış hatch '(Obj.magic in O'Caml'i örnek olarak alın, ancak bunu hack olarak kullanmadım); ancak pratikte birçok program türü için böyle bir cihaza asla ihtiyaç duyulmaz.
Zach Snow

3
Değişkenlerin ayarlanmasının "arzu edilir" olup olmadığı sorusu, alternatif yapıları kullanmanın ne kadar acı verici olduğuna ve değişkenlerin kullanımından ne kadar acıya neden olduğuna bağlıdır. Bu, tüm argümanı reddetmek değil, daha çok "değişkenler son derece arzu edilen bir yapıdır" ifadesini bir aksiyom olarak almanın ikna edici bir argümanın temeli olmadığını belirtmek içindir. Çoğu insanın programlamayı öğrenmesinin yolu budur.
gtd

5
-1: Steve'in ifadeleri kısmen güncel değil ama çoğunlukla tamamen gerçeklere dayalı olarak yanlış. OCaml'ın esnek değer kısıtlaması ve .NET'in tip sistemi, ifadelerine karşı bazı açık örneklerdir.
JD

4
Steve Yegge'in kaputunda statik yazımla ilgili mantıksız bir arı var ve sadece söylediklerinin çoğu yanlış değil, aynı zamanda her fırsatta (ve hatta bazı kullanılamayan fırsatlarda) bunu gündeme getiriyor. Bu konuda yalnızca kendi deneyiminize güvenmeniz iyi olur.
ShreevatsaR

3
Statik ve dinamik yazım konusunda Yegge ile aynı fikirde olmasam da, Haskell Data.Dynamic tipine sahip. Dinamik yazım istiyorsanız, buna sahip olabilirsiniz!
jrockway
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.