Déterminer l'étendue de l'évaluation paresseuse

voix
1

Donné

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)

Ma fonction de compter les nœuds (ce qui semble loin, mais cela est en dehors de la question) est

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)

Ne countpas évaluer le contenu du Msgen vertu de sa valeur étant mis au rebut par _? Peut-être une meilleure question est, comment puis-je savoir où commence l' évaluation paresseuse et se termine pour ce genre de chose?

Si la troisième ligne count'était:

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

Puis - je supposer que les trois autres domaines de l' Msgont été consultés / évalués, ou ne l' évaluation paresseuse aller jusque - là?

Créé 10/10/2011 à 17:38
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

No. Les champs d'une structure de données sont évaluées paresseusement par défaut. Puisque vous n'êtes pas en utilisant les autres champs de toute façon, ils ne seront pas évaluées par ce code. Si vous voulez faire en sorte que l'évaluation d'un nœud de forces tous ses champs à évaluer, vous pouvez ajouter des annotations strictness aux champs:

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 }

Depuis le comptage des noeuds force les nœuds eux - mêmes à évaluer, cela forcera aussi les valeurs de nœud à évaluer. Si vous ne souhaitez que ce comportement pour votre une fonction, vous pouvez forcer l' évaluation d'une manière plus fine en utilisant seq:

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

ou un motif de détonation (nécessite l' BangPatternsextension)

count' (Node !x l r) = [1] ++ count' l ++ count' r
Créé 10/10/2011 à 17:56
source utilisateur

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