SORU
14 EYLÜL 2012, Cuma


Güzel bir şekilde işlevini imza Haskell daha bilgilendirici yapmak için var mı?

Bu kapalı olması yerine, belki de Programcıları göç olacağını ümit ediyorum. öznel ya da konu dışı belki bir soru olarak kabul edilebilir potansiyel fark ettim.

Haskell, çoğunlukla kendi merakım için öğrenmeye başladım, ve fikir ve prensiplerin dil desteği çok severim. Oldum hayran fonksiyonel diller aldıktan sonra bir dil teorisi dersi nerede oynadık etrafında Lisp, ve ben duyuyorum çok iyi şeyler hakkında ne kadar üretken Haskell olabilir, bu yüzden iyi olacağını düşündüm araştırmak kendim. Şimdiye kadar, bu dil, sadece uzak alamıyorum tek bir şey hariç: O anne işlev imzaları lanetli.

Profesyonel geçmişim çoğunlukla OO, özellikle Java ile yapıyor. Çalıştığım yerlerin çoğu standart modern dogmalar; Çevik, Temiz Kod, TDD, vb bir sürü sarhoş var. Çalışma birkaç yıl sonra bu şekilde, kesinlikle benim konfor bölgesi haline geldi ve bu fikir, bu "iyi" kod kendini belgeleyen olmalıdır. özellikle Ben var olmak kullanılmış için çalışan bir IDE, uzun ve ayrıntılı yöntem adları ile çok açıklayıcı imzaları var olmayan bir konu ile Akıllı Otomatik tamamlama ve çok büyük bir dizi analitik araçlar için navigasyon paketleri ve semboller; eğer ben vurmak Ctrl Alanı içinde Tutulması, sonra anlamak ne bir yöntemdir yapmaktan bakıyor adını ve yerel olarak kapsamlı değişkenleri ile ilişkili argümanlar yerine yukarı çekilmesi JavaDocs, ben kadar mutlu bir domuz kakası.

Bu, kesinlikle, Haskell toplum en iyi uygulamalarının bir parçası değildir. Bu konuda farklı görüşler bol okudum, ve Haskell toplum olma succinctness gördüğü anlıyorum"". pro How To Read Haskell ve bir çok kararları arkasındaki mantığı anlıyorum, ama onları seviyorum anlamına gelmez; bir mektup değişken adları, vb ile gittim. eğlenceli benim için değil. Eğer dil ile hack devam etmek istiyorsam buna alışmak zorunda kalacağımı kabul ediyorum.

Ama işlev imzaları kendimi alamıyorum. Learn you a Haskell[...]'fonksiyonu s bölümü sözdizimi: . çekti bu örnek alırsak,

bmiTell :: (RealFloat a) => a -> a -> String  
bmiTell weight height  
    | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!"  
    | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"  
    | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!"  
    | otherwise                   = "You're a whale, congratulations!"

Bu sadece açıklayan korumaları ve sınıf kısıtlamaları amacıyla oluşturulan saçma bir örnek olduğunu, ama eğer incelemek için olsaydı fark ettimsadecebu işlev imzası, kilo vermesi planlanan veya yüksekliği hiçbir fikrim olurdu. Eğer herhangi bir tür yerine Float Double kullanmak olsaydı bile, yine de hemen belirgin değildir.

İlk başta, sevimli ve zeki ve parlak olması ve birden fazla sınıf kısıtlamaları ile uzun tipi değişken adlarını kullanarak taklit etmeye çalışırdım düşündüm:

bmiTell :: (RealFloat weight, RealFloat height) => weight -> height -> String

Bu bir hata (eğer biri bana açıklayabilir hata varsa bir kenara, minnettar olurum) tükürdü:

Could not deduce (height ~ weight)
    from the context (RealFloat weight, RealFloat height)
      bound by the type signature for
                 bmiTell :: (RealFloat weight, RealFloat height) =>
                            weight -> height -> String
      at example.hs:(25,1)-(27,27)
      `height' is a rigid type variable bound by
               the type signature for
                 bmiTell :: (RealFloat weight, RealFloat height) =>
                            weight -> height -> String
               at example.hs:25:1
      `weight' is a rigid type variable bound by
               the type signature for
                 bmiTell :: (RealFloat weight, RealFloat height) =>
                            weight -> height -> String
               at example.hs:25:1
    In the first argument of `(^)', namely `height'
    In the second argument of `(/)', namely `height ^ 2'
    In the first argument of `(<=)', namely `weight / height ^ 2'

Anlamak değil tamamen neden işe yaramadı, başladım Googling ve ben bile buldum bu küçük yazı gösteriyor adlandırılmış parametreleri, özellikle spoofing named parameters via newtype, ama görünüşe göre biraz fazla.

Kabul edilebilir şekilde bilgilendirici işlev imzaları zanaat yok? "Haskell" her şeyi bok Mezgit için sadece?

CEVAP
14 EYLÜL 2012, Cuma


Bir tür imza Java tarzı bir imza değil. Java tarzı bir imza sadece parametre türleri ile parametre adları karıştı çünkü ağırlığı ve yüksekliği olan söyleyecektir. Haskell fonksiyonları gibi desen eşleştirme ve birden fazla denklem kullanılarak tanımlanan, çünkü genel bir kural olarak bunu yapmak için:

map :: (a -> b) -> [a] -> [b]
map f (x:xs) = f x : map f xs
map _ [] = []

Burada ilk parametre ilk denklemi ve _ 12 *adlı oldukça fazla anlamına gelir ("") adı açıklanmayan ikinci. İkinci parametre yokvarbir isim ya da denklemi; ilk bölümden bu isimler (ve muhtemelen programcı olarak düşün "x'ler listesi"), ikinci tamamen değişmez ifade.

Ve sonra nokta-ücretsiz tanımları var:

concat :: [[a]] -> [a]
concat = foldr (  ) []

Yazın imza ** 15, ama bu parametrenin adı görüntülenir türü olan bir parametre alır söylerher yerdesistem.

Bir işlev için ayrı bir denklem dışında, bağımsız değişkenleri ifade etmek için kullandığı isimler alakasız zatenhariçbelgeler gibi. Yılından bu yana fikri bir "canonical name" için bir işlev parametre değil iyi tanımlanmış Haskell, yer bilgilerini "ilk parametre bmiTell ağırlığı temsil ederken, ikinci temsil yüksekliği" belgeleri, türü imzası.

Bir işlev yaptıklarını kristal "ortak" bilgi bu konuda mevcut. temiz olması kesinlikle katılıyorum Java, işlev adı ve adları ve parametre türleri. Eğer çoğu zaman olduğu gibi) kullanıcı, daha fazla bilgi gerekiyorsa, belgelere ekleyin. Bir fonksiyon hakkında genel bilgi Haskell olduğunu fonksiyonun adı ve parametre türleri. Eğer kullanıcı daha fazla bilgiye ihtiyacım var, seni belgelerinde ekleyin. Leksah gibi Haskell için not IDEs kolayca Mezgit yorumlar gösterecektir.


Güçlü ve etkileyici tür bir sistem ile bir dilde yapmak için tercih edilen şey genellikle mümkün olduğu kadar çok hata türü hata olarak algılanabilir olun. Haskell gibi unutmayın. Böylece, bmiTell gibi bir işlevi hemen aşağıdaki nedenlerden dolayı benim için: uyarı işaretleri ayarlar

  1. Aynı tür farklı şeyleri temsil eden iki parametre alır
  2. Eğer yanlış sırayla parametreleri geçti eğer yanlış bir şey yapacak
  3. İki tür doğal pozisyon 18 *iki bağımsız değişkeni gibi) yok

Genellikle tür güvenliğini artırmak için yapılan bir şey aslında newtypes, bulduğunuz link olarak. Çok daha açık bir şekilde temsil eden bir veri türü yapıyor hakkında bu parametre geçirmeden adlı alakası olmadığı gibi bu sanmıyorumyükseklikbir sayı ile ölçmek istersen başka miktar yerine. Ben De Öyle Düşünüyorumolmaznewtype değerleri sadece çağrı at gibi görünecek; yükseklik verileri var her yerde newtype değeri kullanıyor olurdumdande, ve ben bu tür güvenliği (ve belgeler) her yerde fayda elde böylece etrafında bir sayı olarak yükseklik veri olarak yerine geçen. Sadece yükseklik (bmiTell içinde aritmetik işlemleri gibi) bu sayılar üzerinde çalışır bir şey için değil, onu geçmek istiyorum ne zaman ham bir sayı değeri paketini açmak istiyorum.

Not: bu, hiçbir çalışma zamanı havai; newtypes temsil edilir, aynı şekilde veri "içinde" newtype sarıcı, böylece kaydırma/kaydırma işlemleri hiçbir harekat temel temsil ve yalnızca derleme sırasında kaldırıldı. Kaynak kodu ek karakterler sadece ekler, ama bu karakterleritam olarakbelgelere sensin arayan, yararı olmak zorunlu derleyici tarafından; Java tarzı imzalar söyle hangi parametre ağırlık ve yükseklik olduğunu, ancak derleyici hala mümkün olmayacaktır söylersem yanlışlıkla geçti onlara yanlış yol!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • GoogleTechTalks

    GoogleTechTa

    15 AĞUSTOS 2007
  • HuskyStarcraft

    HuskyStarcra

    4 HAZİRAN 2009
  • Julia Graf

    Julia Graf

    6 Mayıs 2006