Determinarea gradului de evaluare leneș

voturi
1

Dat

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)

Funcția mea de a conta noduri (care pare off, dar asta în afară de întrebare) este

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)

Oare countnu evaluează conținutul Msgvirtuții prin valoarea sa fiind eliminate prin _? Poate o întrebare mai bună este, cum știu începe de evaluare în cazul în care leneș și se termină pentru acest tip de lucru?

În cazul în al treilea rând a count'fost:

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

Pot să presupun că celelalte trei domenii ale Msgau fost accesate / evaluate, sau nu de evaluare leneș merge atât de departe?

Întrebat 10/10/2011 la 17:38
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
1

Nu. Domeniile de o structură de date sunt evaluate alene în mod implicit. Din moment ce nu utilizați celelalte câmpuri în orice mod, acestea nu vor fi evaluate de acest cod. Dacă doriți să-l facă, astfel încât evaluarea unei forțe de nod toate domeniile sale care urmează să fie evaluate, puteți adăuga adnotări strictețea la câmpurile:

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 }

Deoarece numărarea nodurile forțează nodurile ei înșiși să fie evaluate, acest lucru va forța , de asemenea , valorile de nod care urmează să fie evaluate. Dacă doriți doar acest comportament pentru o funcție, puteți forța de evaluare într - un mod mai cu granulație fină , folosind seq:

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

sau un model bang (necesită BangPatternsextensia)

count' (Node !x l r) = [1] ++ count' l ++ count' r
Publicat 10/10/2011 la 17:56
sursa de către utilizator

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