2017-07-25 4 views
1

Ich mache eine Codierung Herausforderung in Codewar: Schreiben Sie Funktion avg, die Durchschnitt der Zahlen in der angegebenen Liste berechnet. Meine Lösung funktioniert, aber ich verstehe eine der Lösungen anderer nicht ganz. Kann mir jemand erklären?Können einige erklären, wie der folgende Code funktioniert?

avg :: [Float] -> Float 
avg = (/) <$> sum <*> fromIntegral . length 

Sollte es nicht sein:

avg l = pure (/) <*> sum l <*> fromIntegral . length $ l 
+0

Ist es nicht ein * Herausforderung * für Sie, nicht wir? –

+1

Sie können es auch schreiben als 'liftA2 (/) sum (fromIntegral. Length)' – Khundragpan

+6

'rein f <*> x = f <$> x' – melpomene

Antwort

3

Dieser Code verwendet die Applicative Instanz des (->) a Typ, der here wie folgt definiert ist:

instance Applicative ((->) a) where 
    pure = const 
    (<*>) f g x = f x (g x) 

können Sie diese Implementierung interpretieren, indem sie denke an naryFunction <$> f1 <*> f2 <*> ... <*> fn als "den gleichen Parameter auf alle n Funktionen anwenden und die resultierenden Argumente auf naryFunction anwenden".

In Ihrem Fall kann (/) <$> sum <*> fromIntegral . length als \ xs -> (/) (sum xs) ((fromIntegral . length) xs) gedacht werden, die nur sum xs/fromIntegral (length xs) ist.

Sie können dies unter Beweis stellen, indem Sie einfach Ihren Ausdruck mit der Definition von (<*>) erweitert:

avg = (/) <$> sum <*> fromIntegral . length 
avg = fmap (/) sum <*> fromIntegral . length 
avg xs = (fmap (/) sum) xs ((fromIntegral . length) xs) 
avg xs = ((/) . sum xs) (fromIntegral (length xs)) -- fmap f g = f . g 
avg xs = sum xs/fromIntegral (length xs) 
Verwandte Themen