2011-09-10 18 views
8

Haskell hakkında harika bir şey. Bir fonksiyonun türü neredeyse onun uygulanmasını belirler. Yani bu birinde böyle bir durum, ama beynim sadece burada iç içe işlev şey etrafında sarma değildir ...:Bu işlev, Haskell'de nasıl uygulanır

mkDyn :: (Typeable a) => ((a -> IO()) -> IO()) -> ((Dynamic -> IO()) -> IO()) 

tek soru gerekecektir fromDynamic çağrı hata işlemeye nasıl kontrol edileceğidir, ama ... geri kalanını bulduktan sonra bununla başa çıkabilirim. Sanırım bir yerlerde aşağıdaki gibi bir şey olması gerekecek. Ama sanki sarıcı lambda eşyalarını anlayamıyorum.

case fromDynamic x of 
    Just x -> f x 
    Nothing -> undefined -- TODO 
+1

Vay, Haskell'in dinamik bir destek aldığını bile bilmiyordum, bu sadece [üs altında] olduğunu söyledi (http://hackage.haskell.org/packages/archive/base/latest/doc/html/ Veri Dynamic.html). Her gün yeni bir şey öğrenin. –

+0

@Joey IIRC, kolay atama operatörleri ile zorunlu stil kodu yazmak için bir kütüphane bile var, ama nerede unuttum. Bir kez Planet Haskell'de bahsedildiğini düşünüyorum. – fuz

cevap

10

Sana toDyn değil fromDynamic istediğini düşünüyorum.

mkDyn :: Typeable a => 
     ((a -> IO()) -> IO()) 
     -> (Dynamic -> IO()) 
     -> IO() 
mkDyn k f = ... 

Bizim döndürme türü IO() olmalı ve biz k veya f arayarak ya o edinebilirsiniz: Yani en yavaş yapalım. f numaralı telefondan arama yapmak bize bir fayda sağlamaz, çünkü bir şekilde bir Dynamic maddesini gerçekleştirebiliriz, ancak bunu k'dan (mantıklı bir şekilde) yapamayız. Yani k'u aramak istiyoruz.

mkDyn k f = k (\a -> ...) 

Yani işlevin argümanı Typeable a => a -> IO() geçerli: k yüzden böyle başlatmanızı sağlar, onun argüman olarak başka işlevi ihtiyacı vardır. Bu tür bir işlevimiz yok, ancak Dynamic -> IO() türünde bir işlevimiz var. Typeable sınırlaması biz Dynamic içine bizim a açmak ve almak için toDyn kullanabildiği için:.

mkDyn k f = k (\a -> f (toDyn a)) 

daha basit uygulamalar (örneğin return() veya k (\a -> return()), ama bu bir anlam ifade görünmektedir vardır

+0

mkDyn k f = k $ f. toDyn – rampion

+3

@rampion İki kişi bu oyunu oynayabilir! mkDyn = (. (. toDyn)) '. –

+2

İşaretli sürümleri tercih etme eğilimindeyim. Sadece gerçekten basit bir boru hattı ise, sadece nokta-serbest stil kullanıyorum. Herhangi bir şey (biraz bile olsa) daha karmaşık ve bir dahaki sefere kodu okurken pişman olurum. – nominolo

4

aldattım ve Djinn program kullanılan

ilk verilen türünü genelleştirilmiş.

f :: (a -> c) 
    -> ((a -> b) -> b) 
    -> ((c -> b) -> b) 

(a -> c), toDyn function işlevini temsil eder ve c, Dynamic'u temsil eder. b, IO()'u temsil eder.

DJiNN en sonuç şaşırtıcı basitti:

@djinn (a -> c) -> ((a -> b) -> b) -> ((c -> b) -> b) 
f a b c = b (\ d -> c (a d)) 

daha spesifik (toDyn fonksiyonu ile (a -> c) değiştirerek) Yapımı, elde ederiz:

mkDyn :: (Typeable a) => ((a -> IO()) -> IO()) -> ((Dynamic -> IO()) -> IO()) 
mkDyn b c = b (\ d -> c (toDyn d)) 

nominolo's answer eşleşir.

+1

Bu, nominolo'nun bir cin olduğunu kanıtlıyor mu? – Landei