2017-02-27 16 views
0

Ich habe folgenden CodeDividieren alle Haskell Arraywerte mit ihrem gcd

reducer :: Row El -> Row El 
reducer r = let getGCD l = map (\x y -> gcd x y) l 
       gcd' = getGCD r 
       f = (\x -> map (\y -> y * gcd') x) 
      in (f (r)) 

, um ein Array mit gcd zu unterteilen.

reducer [8,8,12] :: Row Int 
-- > [2,2,3] 

aber ich konnte nicht verwalten zu reducer :: Row El -> Row El Funktionstyp passen, so dass im Grunde funktioniert Code nicht.

Wie kann ich es beheben?

+1

'map' erwartet eine Funktion vom Typ' a -> b'; Sie stellen einen vom Typ 'a -> b -> c 'zur Verfügung. – chepner

Antwort

1

Der GCD mit 3 oder mehr Zahlen muss unter Berücksichtigung der Zahlen berechnet werden. Der einfachste Weg, dies zu tun, besteht darin, den GCD des Schwanzes der Liste rekursiv zu berechnen und dann den GCD dieses Wertes und den Kopf zu berechnen. Da gcd x 0 == x für jedes x, können wir den Basisfall definieren zu 0. (auch Haskell-Implementierung von gcdgcd 0 0 == 0 definiert.)

getGCD [] = 0 
getGCD (x:rest) = gcd x (getGCD rest) 

Sobald Sie, dass, können Sie die GCD Ihrer Liste finden, dann divide jede Zahl von der GCD.

reducer r = let gcd' = getGCD r 
      in map (\x -> div x gcd') r 
+0

es funktioniert nicht. – yusuf

+0

was funktioniert nicht? - Die Berechnung des gcd - oder des Reducers und auf welche Art und Weise - kompiliert nicht oder erzeugt eine unerwartete Ausgabe - ich denke @chepner hätte vielleicht einen Fall 'getGCD [x] = x' weggelassen. – epsilonhalbe

+0

'getGCD' ist falsch; Ich werde es reparieren. – chepner

2

GCD von mehreren Nummern:

gcd' = foldl gcd 0 :: (Integral b, Foldable t) => t b -> b 

die Sie dann alle Zahlen im Array teilen verwenden können:

div' xs = map (`div` g) xs 
    where 
    g = gcd' xs