2015-03-23 38 views
6

Bir işlev yazdığım her zaman, henüz var olmayan bir düzine başka işlev çağırır. Açıkçası sonunda var olacaklar, ama kodu yazmayı bitirmeden önce bir sözdizimi kontrolü yapabilmek güzel olurdu. "foo adı kapsamı değil" hatalarından ziyade GHC yayma uyarısı yapmak için kullanabileceğim bazı bayrak kombinasyonları var mı?GHC, kapsam dışı hataları göz ardı etmeyin

(O GHC sadece var olmayan adları için bir tür imza almak olabilir aslında eğer güzel ve. Bu neredeyse neyi "tip delikler" dır hala programı yazın-kontrol etmek için mümkün olduğunu teyit edeceği özelliği — ama bu kullanmak için, yine de el tüm tanımlama yapabilmemize var)

+3

Sadece imzayı ve bu işlevler için bir '= undefined' yazmayı iyi bir uygulama olarak görüyorum ... ama, iyi bir soru, bazen fikirler için bu denemeye değer olduğundan emin değilim. onları ayrıştırmadıklarından, onları yazım denetimi yapmak için. – leftaroundabout

+0

Doğru sözdiziminin doğru olup olmadığını kontrol etmenin bir başka yolu da "pointfree" gibi bir şey kullanmak ve "Ayrıştırma hatası: EOF" seçeneğini işaretlemektir, ancak bu, tek satırlı bir ifadeden daha fazlasını yapmakta zorlanır. – bheklilr

+0

@leftaroundabout Benim durumumda, bir çözümleyici yapıyorum. Yani, yüzlerce * olmayan, mevcut olmayan tanımlayıcılar var, bunların hepsi parser olmalı. Sonunda tüm parçaları yazmayı bitirdiğimde işe yaramalı. Ama son noktaya gelmeden önce sözdizimi hatalarını yakalamak güzel olurdu ... – MathematicalOrchid

cevap

11

Kullanım TypedHoles adında. Yani bu sana verdiği

> let f x = _g . _h x $ x 
    Found hole ‘_g’ with type: b0 -> c 
    Where: ‘b0’ is an ambiguous type variable 
      ‘c’ is a rigid type variable bound by 
       the inferred type of f :: s -> c at <interactive>:2:5 
    Relevant bindings include 
     x :: s (bound at <interactive>:2:7) 
     f :: s -> c (bound at <interactive>:2:5) 
    In the first argument of ‘(.)’, namely ‘_g’ 
    In the expression: _g . _h x 
    In the expression: _g . _h x $ x 

    Found hole ‘_h’ with type: s -> s -> b0 
    Where: ‘b0’ is an ambiguous type variable 
      ‘s’ is a rigid type variable bound by 
       the inferred type of f :: s -> c at <interactive>:2:5 
    Relevant bindings include 
     x :: s (bound at <interactive>:2:7) 
     f :: s -> c (bound at <interactive>:2:5) 
    In the expression: _h 
    In the second argument of ‘(.)’, namely ‘_h x’ 
    In the expression: _g . _h x 

_g :: b0 -> c veo x :: s ve f :: s -> c bağlamında. Tip-kontrol edici, bu türlerin çoğunu bu zamana dönüştürebilir (bu, TypedHoles'un noktasıdır) ve onlara isimleri verebilirsiniz. İsterseniz, tüm fonksiyonlarınızı _ sembolü ile sembol isminin ilk karakteri olarak tanımlayabilirsiniz, daha sonra 'u \1 ile değiştirmek için editörünüzü kullanın. Bir kayıt alanı için _name kullanmanın lens sözleşmesi etrafında çalışmak istiyorsanız, o zaman sadece delik adınıza 2 alt çizgi koydu.

Bu, kodunuzun derlemesini yine de yapmaya devam edecektir, ancak bunu -fdefer-type-errors ile birlikte kullanacaksanız, bunlar çalışma zamanında tür hatalarınızın oluşmasına izin verecek şekilde uyarı olarak bildirilecektir.

+0

Yani tüm tanımlayıcıları bir altçizgi ile başlatıp "-fdefer-type-errors" işlevini açıp açmayacağımı söylüyorsanız, kabaca istediğim davranışı alacağım? – MathematicalOrchid

+1

@MathematicalOrchid Az ya da çok, ne istediğini anlıyorum.Tanımlayıcılarınız sadece bir delik açmak için '_' ile başlamalı, GHC bu deliğin türünü girer, GHC normalde bunun için bir derleme hatası yayar ancak' -fdefer-type-errors 'bunları bile uyarır. Programınızı bir deliğin ortaya çıktığı noktaya kadar çalıştırın, bu yüzden f = putStrLn "test" ye izin verin >> _foo; '' '' test' yazdıracaktır, sonra '-fdefer-type-errors' olmadan derleme zamanında aldığınız tam hata mesajını içeren bir istisna gösterecektir. – bheklilr

+2

@MathematicalOrchid dfeuer ve leftaroundabout işaret ettikleri gibi, tip imzaları ile tanımlamak ve 'undefined' derlemek için herhangi bir ekstra bayrak gerektirmez ve hata iletilerini geliştirir, aynı zamanda gerekli olan her şey yerine ifadelerinizin istenen türlere sahip olmasını sağlar sadece bunu yapmak için. için "hata" deliği adı "ve ifadesiyle türetilmiş adlandırılmış bir deliği çıkarıp çıkartabileceğiniz bir eklenti yazabileceğinizi düşünün, daha sonra delikleri dışa vurmak bir" tümünü ayıkla "komutuyla bir esinti oluşturacaktır. – bheklilr

3

Her zamanki yaklaşımım, eksik işlevleri veya değerleri undefined olarak tanımlamaktır. Tanımlanması kolaydır ve söz konusu işlevin henüz tanımlanmadığını gösteren uygun bir işaretçi bırakır.

Bunun OP'nin sorusuna cevap vermediğinin farkındayım, çünkü işlevler hala elle tanımlanmak zorundadır, ancak yine de yararlı olabileceğini düşündüm.

İlgili konular