Рассмотрим знаменитый
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Предположим, что, чтобы избежать ограничения мономорфизма, это аннотируется с:
fibs :: Num a => [a]
Это означает, что во время выполнения значение списка fibs
действительно не существует, а скорее функция, которая вычисляет список заново каждый раз, когда выбран элемент fibs
?
Вопрос в том, как такие случаи фактически обрабатываются в разных реализациях Haskell, о которых вы знаете.
--- ДОБАВЛЕНО ---- Я чувствую, что я должен уточнить немного больше. Рассмотрим:
fibsInteger :: [Integer]
fibsInteger = 0: 1: zipWith (+) fibsInteger (tail fibsInteger)
и предположим, что во время выполнения программы значение
(fibsInteger !! 42)
необходимо оценить. В этом случае я ожидал бы, что последующие оценки, подобные этому, обнаружат, что первые 43 элемента fibsInteger
уже оценены. Это означает также, что fibsInteger
сам и первые 42 его хвоста уже находятся в WHNF.
Но это было бы невозможно с полиморфным fibs
, насколько я вижу. Замечание FUZxxl
потому что класс типа обычно вводит новый аргумент, содержащий словарь с функциями этого класса
похоже, поддерживает мое мнение, что значение, подобное fibs
, эффективно отображается как функция во время выполнения?
Если бы это было так, то приложение, подобное ((maximum . map (fibs!!)) [100000 .. 101000] :: Integer)
shold, получило значительно больше времени для оценки, чем неполиморфный вариант ((maximum . map (fibsInteger!!)) [100000 .. 101000] :: Integer)
, потому что первые 100000 номеров нужно будет пересчитывать каждый раз.
(К сожалению, я не могу попробовать это в это время)