Bestimmung des Ausmaßes der lazy evaluation

stimmen
1

Gegeben

data BTree a = End
             | Node a (BTree a) (BTree a)
   deriving(Show,Eq,Ord)

data Msg = Msg { from :: String
               , to :: String
               , when :: Int
               , message :: String }

instance Ord Msg where
    compare a b = (when a) `compare` (when b)

instance Eq Msg where
    (==) a b = (when a) == (when b)

Meine Funktion zu zählen Knoten (das scheint weg, aber das ist abgesehen von der Frage) ist

count :: (Ord a) => (BTree a) -> Int
count = sum . count'
 where
  count' :: (Ord a) => (BTree a) -> [Int] 
  count' End = []
  count' (Node _ l r) =
    [1] ++ (count' l) ++ (count' r)

Hat countbewerten nicht den Inhalt der Msgaufgrund seines Wertes wird verworfen durch _? Vielleicht eine bessere Frage ist, wie kann ich wissen , wo lazy evaluation beginnt und endet für diese Art der Sache?

Wenn die dritte Zeile count'war:

count' (Node (Msg x _ _ _) l r) =

Kann ich davon ausgehen , dass die anderen drei Bereiche Msgwurden zugegriffen / ausgewertet, oder nicht faul Auswertung so weit gehen?

Veröffentlicht am 10/10/2011 um 17:38
quelle vom benutzer
In anderen Sprachen...                            


1 antworten

stimmen
1

Nein. Die Felder einer Datenstruktur werden lazily standardmäßig bewertet. Da Sie nicht auf die anderen Felder in irgendeiner Weise verwenden, werden sie nicht durch diesen Code ausgewertet werden. Wenn Sie wollen, es zu machen, so dass ein Knoten Kräfte Auswertung aller seiner Felder ausgewertet werden, können Sie Strikt Anmerkungen zu den Feldern hinzu:

data BTree a = End
             | Node !a (BTree a) (BTree a)
   deriving(Show,Eq,Ord)

data Msg = Msg { from :: !String
               , to :: !String
               , when :: !Int
               , message :: !String }

Da die Knoten Zählen der Knoten zwingt selbst ausgewertet werden, wird dies auch dazu zwingen , die Knotenwerte ausgewertet werden. Wenn Sie dieses Verhalten nur für eine Funktion möchten, können Sie Auswertung in einer feinkörnigen Art und Weise unter Verwendung von Kraft seq:

count' (Node x l r) = x `seq` ([1] ++ count' l ++ count' r)

oder ein Bang - Muster (erfordert die BangPatternsErweiterung)

count' (Node !x l r) = [1] ++ count' l ++ count' r
Beantwortet am 10/10/2011 um 17:56
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more