2015-07-01 18 views
10

From the chapter on Functors in Learn You a Haskell for Great Good, Lipovača devletler: Biz (+) <$> (+3) <*> (*100) yaptığımızda

", biz + kullanacağı bir işlev yapıyoruz (+3) ve (*100) ve sonuçları bu dönün. gerçek bir örnek üzerinde göstermek için biz (+) <$> (+3) <*> (*100) $ 5 yaptığımız zaman, 5 ilk 8 ve 500 sonuçlanan (+3) ve (*100) uygulanan gördü. Daha sonra, +8 ve 500, res ile çağrılan 508'da son nokta. " Ben funktor üzerinde uygulamalı bu tanımı göz önüne alındığında, fonksiyonu kendim değerlendirmek için deneyin

Bununla birlikte, ((->) r):

instance Applicative ((->) r) where 
    pure x = (\_ -> x) 
    f <*> g = \x -> f x (g x) 

yukarıda ifade olarak değerlendirilmesini şöyledir:

(\x -> (3 + x) (100 * x)) $ 5

Ama biz aslında (tek lambda olarak iki kısmen uygulanan ikili işlevlerini oluşturabilirsiniz nasıl görmüyorum, GHCi bu bağlamaya çalışırken sonsuz tip hata atar bir değişken).

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

veya daha spesifik biz olarak kaldırma bakabilirsiniz: biz <$> tip tanımına bakarsak Ayrıca, çalışma yorumlamaya, biz olsun düşünülürse

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

Bu durumda bizim functor ((->) r), ben bu dönüşüm önceki değerlendirme (5 doğru çağrıştırma uygulaması yerine, ilk önce sol birliği olduğunu varsayarak) gerçekleştiği olduğunu söyleyebiliriz:

(\x -> a + b) burada a = (+ 3) ve = (* 100)b. Bu, iade edilmesi gereken işlevdir. Ancak, bunun son (kaba) bir form olduğunu varsayarak düzeliyorum mu? 508.

verir

(\x -> (3 + x) + (100 * x)) $ 5

... altında gorey detaylar için tamamen doğru değildir ben ifadesi nasıl çalıştığını açısından daha anlaşılır Lipovača açıklamasını bulmak, ama benim bağırsak söylüyor Haskell derleyici kukuleta. Önce (+) 'nın fmap'inin, paylaşılan girdiyi alan fonksiyonların kısmen uygulandığı iki functor ile sonuçlanan bir fonksiyona yol açtığını düşünmemiz daha kolay olur ve sonra ona bir değer uyguladık. Bunu tembel değerlendirme nedeniyle yapabiliriz. Bu yanlış mı?

+1

"de yukarıda ifade değerlendirme okumak:

(#) :: (a -> b) -> a -> b f # a = f a infixl 0 # 

ve GHCi içinde

'(\ x -> (3 + x) (100 * x)) 5 $ ". İpucu: değerlendirmeniz '((+) <$>)' türünde bir hata eksik. – duplode

+0

Evet, bu yüzden devam ediyorum ve ikinci yarısına dahil ediyorum. – RJS

+0

Oops - boşver, sorunun orta kısmını yanlış okumuştum. – duplode

cevap

15

İlk olarak, <$> ve <*> öğelerinin her ikisinin de sola ilişkilendirildiğini unutmayın. İçsel olarak büyülü bir şey olmuyor ve dönüşümü aslında bir dizi eta genişlemesi ve beta azaltımı ile görebiliyoruz.Adım adım, bu şuna benzer:

(((+) <$> (+3))   <*> (*100)) $ 5  -- Add parens 
((fmap (+) (+3))  <*> (*100)) $ 5  -- Prefix fmap 
(((+) . (+3))   <*> (*100)) $ 5  -- fmap = (.) 
((\a -> (+) ((+3) a)) <*> (*100)) $ 5  -- Definition of (.) 
((\a -> (+) (a+3))  <*> (*100)) $ 5  -- Infix + 
((\a b -> (+) (a+3) b)) <*> (*100)) $ 5  -- Eta expand 
(\x -> (\a b -> (+) (a+3) b) x ((*100) x)) $ 5 -- Definition of (<*>) 
(\x -> (\a b -> (+) (a+3) b) x (x*100)) $ 5 -- Infix * 
(\a b -> (+) (a + 3) b) 5 (5*100)    -- Beta reduce 
(\a b -> (a + 3) + b) 5 (5*100)    -- Infix + 
(5 + 3) + (5*100)        -- Beta reduce (twice) 
508           -- Definitions of + and * 

A, karışıklığa sağa $ ilişkilendirdiğinden fixity olmasından daha burada neler ilgisi az olduğu gerçeğini bit 0. görebiliyoruz Bu yeni bir operatöre tanımlarsak:

λ> (+) <$> (+3) <*> (*100) # 5 
508 
+0

Bunun için teşekkürler, bu tam olarak aradığım şey. Eta ve Beta genişlemesine daha fazla bakmak ve gelecekteki okuma için azaltma yapmak zorunda kalacağım. "$" Doğru çağrışımcı olsa da, bir thunk'a uygulanmakta ($ thunk'un solundaki tüm haritalamayı çağırmak güvenli midir?) Ve dolayısıyla tüm bunlar değerlendirilir, değil mi? – RJS

+0

@RJS "f $ a", "f" (a) "gibi davranan" f "ve" a "sözcüklerinin boşluklara sahip olabileceğini düşünebilirsiniz. özellikle de "$' ler zincirlendiğinde, ama ben genellikle böyle düşünürüm). Sabitlük hakkında biraz ekledim, muhtemelen genişlemeliyim. Aslında, '' '' '' '' '' '' '' '' '' '' '' '' '' '' sol birleşik, '' 'yapmak için bir (oldukça iyi) argüman vardır. Bir thunk olmanın nasıl alakalı olduğundan emin değilim. Bununla ne demek istiyorsun? –

+0

Ah sadece benim yanımda yanlış anlambilim; Tüm değerlendirilmemiş argümanların birer olağan dışı olduğu varsayımı tümüyle zayıftır. – RJS

İlgili konular