Я изучаю Haskell в настоящее время (будучи программистом по профессии, но это моя первая попытка функционального языка).Почему этот код не является постоянным?
Я хочу написать функцию, которая сканирует список и возвращает как минимальный, так и максимальный элемент этого списка. В зависимости от того, что делают функции Prelude minimum
и maximum
, но оба они одновременно. Я придумал следующий код:
import Data.List
-- Declaration of rand
minMax :: [Int] -> Maybe (Int, Int)
minMax [] = Nothing
minMax (x:xs) = Just (foldl' f (x, x) xs)
where
f (a, b) c = (if c < a then c else a, if c > b then c else b)
rand
это функция, которая порождает бесконечный список чисел. Дело в том, что, когда я добавляю следующую main
функцию:
main = print $ minMax $ take 1000000 $ rand 7666532
компилировать и запускать все это с профилированием, он показывает мне, она использует более 200 Мб оперативной памяти, так что это определенно не является функцией постоянного пространства (которое Я бы хотел, чтобы это было).
Вопрос в том, почему и что я должен изменить, чтобы исправить это. Как я понимаю, foldl'
складывает список слева (так же, как он создан) и не ленится, поэтому я не понимаю, почему использование памяти настолько велико. Я уверен, что это minMax
функция, неверно, так как просто печать указанного списка, используя
main = print $ take 1000000 $ rand 7666532
дает мне использование 1Мб, то, что я понимаю и ожидать.
Пожалуйста, отредактируйте ваш вопрос и добавьте полный код, включая определение «Ранд». Использование строгой левой складки не заставляет оценивать элементы пары, здесь, потому что ваш аккумулятор уже находится в слабой головной нормальной форме, а кортежи ленивы. – Jubobs
Либо перепишите свой код с помощью 'seq', либо определите строгий тип данных пары:' data Pair a b = Pair! A! B' и используйте его вместо простого старого '(a, b)'. – Jubobs
Я хотел бы упомянуть [библиотеку 'foldl'] (https://hackage.haskell.org/package/foldl-1.1.1/docs/Control-Foldl.html), которая абстрактно сочетает такие складки, как это эффективно, в что один из приведенных примеров: 'L.fold ((,) <$> L.minimum <*> L.maximum) [1..10000000]' –