2015-06-18 42 views
12

Dlaczego f <$> g <$> x jest odpowiednikiem (f . g) <$> x, mimo że <$> nie jest stowarzyszeniem prawym?

(Ten rodzaj równoważności jest ważna w a popular idiom zwykły $, ale obecnie $ jest tuż-asocjacyjne!)

<*> ma takie samo skojarzenie i pierwszeństwo jako <$>, ale zachowuje się inaczej!

Przykład:

Prelude Control.Applicative> (show . show) <$> Just 3 
Just "\"3\"" 
Prelude Control.Applicative> show <$> show <$> Just 3 
Just "\"3\"" 
Prelude Control.Applicative> pure show <*> pure show <*> Just 3 

<interactive>:12:6: 
    Couldn't match type `[Char]' with `a0 -> b0' 
    Expected type: (a1 -> String) -> a0 -> b0 
     Actual type: (a1 -> String) -> String 
    In the first argument of `pure', namely `show' 
    In the first argument of `(<*>)', namely `pure show' 
    In the first argument of `(<*>)', namely `pure show <*> pure show' 
Prelude Control.Applicative> 
Prelude Control.Applicative> :i (<$>) 
(<$>) :: Functor f => (a -> b) -> f a -> f b 
    -- Defined in `Data.Functor' 
infixl 4 <$> 
Prelude Control.Applicative> :i (<*>) 
class Functor f => Applicative f where 
    ... 
    (<*>) :: f (a -> b) -> f a -> f b 
    ... 
    -- Defined in `Control.Applicative' 
infixl 4 <*> 
Prelude Control.Applicative> 

Z definicji <$>, spodziewam show <$> show <$> Just 3 na porażkę, zbyt.

Odpowiedz

21

Dlaczego f <$> g <$> x jest odpowiednikiem ?

To nie tyle funktor, co rzecz Haskella. Powodem, dla którego działa, jest to, że funkcje są funktorami. Obaj operatorzy <$> pracują w różnych funktorach!

f <$> g jest w rzeczywistości samo jak f . g, więc równoważność pytasz o to raczej bardziej trywialny niż f <$> (g <$> x) ≡ f . g <$> x.

+1

Dzięki za tę sprytną obserwację! –

+5

No cóż, zauważyłeś to, prawda? Właśnie sparsowałem i sprawdziłem to ... – leftaroundabout

+0

Cóż, chodziło mi o uwzględnienie innej instancji Funktora. Być może "obserwacja" nie jest dobrym słowem na to. –