Niedawno skończyłem learnyouahaskell i starałem się zrozumieć sens ograniczeń monomorfizmu, jak opisano w Wiki Haskell . Wydaje mi się, że rozumiem, w jaki sposób MR może zapobiegać powtarzającym się ocenom, ale nie rozumiem, dlaczego nie można uniknąć tych powtarzanych ocen za pomocą znacznie prostszych środków.
Konkretny przykład, który mam na myśli, to ten używany przez wiki:
f xs = (len,len)
where
len = genericLength xs
gdzie genericLength
jest typu Num a => [b] -> a
.
Oczywiście genericLength xs
do obliczenia wystarczy tylko raz obliczyć (len,len)
, ponieważ jest to ta sama funkcja z tymi samymi argumentami. I nie musimy widzieć żadnych inwokacji, f
aby to wiedzieć. Dlaczego więc Haskell nie może przeprowadzić tej optymalizacji bez wprowadzenia reguły takiej jak MR?
Dyskusja na tej stronie wiki mówi mi, że ma to coś wspólnego z faktem, że Num
jest ona typem, a nie konkretnym typem, ale mimo to, czy nie powinno być oczywiste w czasie kompilacji, że funkcja czysta zwróciłaby tę samą wartość - - a zatem ten sam konkretny typ Num - gdy podano dwa razy te same argumenty?
f [] :: (Int, Float)
. Teraz ma to sens. Dziękuję Ci.It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.
Myślę, że lepszym sposobem patrzenia na to jest to, że instancja klasy jest faktycznie dodatkowym argumentem,genericLength
a kompilator nie jest przekonany, że to te same argumenty w obu wywołaniach.a = uncurry (==) $ f [1, 2, 3]
Czy byłby w stanie zoptymalizować tę witrynę wywołań, aby sprawdzić długość tylko[1, 2, 3]
raz? Jeśli tak, to jestem naprawdę zdezorientowany, co tak naprawdę ogranicza cię monomorfizm, a jeśli nie, to dlaczego nie?