Determinar el alcance de la evaluación perezosa

votos
1

Dado

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)

Mi función para contar los nodos (que parece fuera pero eso es aparte de la cuestión) es

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)

No countno evaluar el contenido de la Msgvirtud de su valor por ser desechados por _? Tal vez una mejor pregunta es, ¿cómo sé aperturas de evaluación donde perezosos y termina para este tipo de cosas?

Si la tercera línea count'fue:

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

¿Puedo asumir que los otros tres campos de Msgse accedió / evaluados, o se van evaluación perezosa tan lejos?

Publicado el 10/10/2011 a las 17:38
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
1

No. Los campos de una estructura de datos se evalúan perezosamente por defecto. Puesto que usted no está utilizando los otros campos de ninguna manera, no van a ser evaluados por este código. Si desea hacerlo de modo que la evaluación de un nodo fuerzas todos sus campos a ser evaluados, se puede añadir anotaciones rigurosidad a los campos:

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 }

Desde contando los nodos obliga a los nodos a sí mismos para ser evaluado, esto también obligará a los valores de nodo para ser evaluados. Si sólo desea este comportamiento para su sola función, se puede forzar la evaluación de un modo más preciso el uso de seq:

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

o un patrón de explosión (requiere la BangPatternsextensión)

count' (Node !x l r) = [1] ++ count' l ++ count' r
Respondida el 10/10/2011 a las 17:56
fuente por usuario

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