Я только что закончил учить вас на днях, и я пытался разобраться в ограничении мономорфизма, как описано в Haskell Wiki . Я думаю, что понимаю, как MR может предотвратить повторные оценки, но я не понимаю, почему этих повторных оценок нельзя избежать гораздо более простыми способами.
Я имею в виду конкретный пример, используемый вики:
f xs = (len,len)
where
len = genericLength xs
где genericLength
типа Num a => [b] -> a
.
Очевидно, что genericLength xs
для вычисления необходимо вычислить только один раз (len,len)
, поскольку это одна и та же функция с одинаковыми аргументами. И нам не нужно видеть никаких призывов, f
чтобы знать это. Так почему же Haskell не может выполнить эту оптимизацию без введения правила, подобного MR?
Обсуждение на этой вики-странице говорит мне, что это как-то связано с тем, что Num
это класс типов, а не конкретный тип, но даже в этом случае, если во время компиляции не должно быть очевидным, что чистая функция будет возвращать то же значение, и, следовательно, тот же конкретный тип Num - когда приводятся одни и те же аргументы дважды?
f [] :: (Int, Float)
. Теперь это имеет смысл. Спасибо.It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.
Я думаю, что лучший способ взглянуть на это состоит в том, что экземпляр класса типов является фактически дополнительным аргументом,genericLength
и компилятор не уверен, что это одни и те же аргументы в обоих вызовах.a = uncurry (==) $ f [1, 2, 3]
сможет ли он оптимизировать этот сайт вызовов, чтобы проверять только длину[1, 2, 3]
один раз? Если так, то я действительно смущен тем, что ограничение мономорфизма действительно покупает вас, если нет, то почему нет?