2013-06-06 43 views
8

no'lu bir yazım hatasıdır. Burada SO üzerinde bazı örnekler buldum ama onları benim durumuma uygulayamadım. Düşünebildiğim tek şey, oldukça çirkin görünen ağır iç içe izin cümlesi.Haskell,

notasyonu yaptığımız

Bildirimi bağlama ile değiştirilmelidir: Herhangi giriş derece takdir edilir

do num <- numberNode x 
    nt1 <- numberTree t1 
    nt2 <- numberTree t2 
    return (Node num nt1 nt2) 

=) bu Applicatives kullanırsanız daha basit olduğunu

cevap

11
numberNode x >>= \num -> 
    numberTree t1 >>= \nt1 -> 
    numberTree t2 >>= \nt2 -> 
     return (Node num nt1 nt2) 

Not:

Node <$> numberNode x <*> numberTree t1 <*> numberTree t2 
+0

Teşekkür. Nedenini bilmiyorum, ama bu basit çözümden henüz değildim. – floAr

+0

Rica ederim! –

7

Bu, applicative style için mükemmel bir kullanım örneğidir. buna da functors çalışır böylece "kaldırma" işlevi uygulaması olarak (<$> ve <*> kullanarak) uygulamalı tarzı

Node <$> numberNode x <*> numberTree t1 <*> numberTree t2 

Think ile (Control.Applicative aktardıktan sonra) tüm pasajı yerini alabilir. Eğer zihinsel olarak <$> ve <*> göz ardı ederseniz, normal fonksiyon uygulamasına çok benziyor!

Uygulama stili, saf bir işleve sahip olduğunuzda ve bunu geçersiz argümanlar (ya da herhangi bir functor argümanı, gerçekten) vermek istediğinizde yararlıdır - temelde sorunuzda belirttiğiniz şeyi yapmak istediğinizde!


<$> tipi imza (bu durumda numberNode x olarak) ve bir funktor değeri (bu durumda Node olarak) saf fonksiyon alan anlamına gelir

(<$>) :: Functor f => (a -> b) -> f a -> f b 

ve bu sarılmış yeni bir fonksiyon oluşturur "iç" bir functor. Sen Gördüğünüz gibi tip imzasını

(<*>) :: Applicative f => f (a -> b) -> f a -> f b 

olan, <*> ile bu işleve başka argümanlar ekleyebilir, bu sadece işlev funktor "içeride" sarılır bile çalışır <$> çok benzer.

fmap :: Functor f => (a -> b) -> f a -> f b 

geçerli:

(<$>) :: Functor f => (a -> b) -> f a -> f b 

sadece fmap benziyor:

+0

Bundan bahsettiğiniz için teşekkür ederim, uygulamalarla ilgili deneyimim yok ama konsept harika görünüyor. Ben Haskell hakkında gibi :) Ben Gabriels cevabını kabul edecek bağlama operatör için soruyordu gibi sorunları çözmek için güzel yollarından sadece bu tür, ama ben kesinlikle bu kavramın daha derinlemesine incelemek alacaktır.) = Bu continuative açıklama için) = bana – floAr

2

Yukarıda applicative hakkında yayınlara eklediği istiyorum ..

<$> türünü göz önüne alındığında Ayrıca Control.Monad gibi.liftM:

action >>= return . f 

sizi: Ben kendine bunu yaparken bulursanız, İlgili bir

"Ben bu tip içine veri yapıcısı kaldırmaya gerek" olarak düşünüyorum

liftM :: Monad m => (a -> b) -> m a -> m b 

yerine bunu yapabilirsiniz:

f `fmap` action 

ilk örnek ne olursa olsun tip faaliyet dışı değerini almaya bağlama kullanıyor onunla çağırarak, ve sonra sonuca yeniden paketleme. Bunun yerine f'yi kaldırabiliriz, böylece argüman olarak eylem türünü alır. Bu kafamı duvara itmek için

+0

sayesinde bu işaret için çok teşekkür ederiz – floAr

+1

'liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 - > m, a3 -> mr' ya da 'liftA3 :: Uygulamalı f => (a -> b -> c -> d) -> fa -> fb -> fc -> fd' 'Control.Monad' içe mevcuttur ya da 'Control.Applicative' ve düz' fmap'/'liftM''den daha faydalıdır. Örneğin, 'liftA3 Düğümü (numberNode x) (numberTree t1) (numberTree t2)' hile yapardı. – AndrewC

+0

Zaten bu soruya cevap vermiyor. OP, sahip oldukları problemi çözmek için kullanamaz. Bu yüzden liftM3 veya Applicative'e ihtiyacınız var. – AndrewC