Определение степени ленивой оценки

голоса
1

Данный

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)

Моя функция для подсчета узлов (которые, кажется, прочь, но это в стороне от вопроса) является

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)

Имеет ли countне оценивать содержание Msgв силу своей стоимости, выбрасываемых _? Может быть, лучше вопрос, как я знаю , где ленивые начинается и заканчивается оценки для такого рода вещи?

Если третья строка count'была:

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

Могу ли я считать , что остальные три поля Msgбыли доступны / оценены, или же ленивые вычисления идут так далеко?

Задан 10/10/2011 в 17:38
источник пользователем
На других языках...                            


1 ответов

голоса
1

Нет. Поля структуры данных оцениваются лениво по умолчанию. Так как вы не используете другие поля в любом случае, они не будут оценены этим кодом. Если вы хотите сделать так, чтобы оценивать Узел силу весь его поле должны быть оценено, вы можете добавить строгость аннотации к полям:

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 }

Так как узлы подсчета вынуждает узлы сами по себе должны быть оценены, это также заставит значения узлов , которые будут оценены. Если вы хотите только это поведение для вашей одной функции, вы можете заставить оценку в более мелкозернистой способом с использованием seq:

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

или модель взрыва (требует BangPatternsрасширений)

count' (Node !x l r) = [1] ++ count' l ++ count' r
Ответил 10/10/2011 в 17:56
источник пользователем

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