Jestem nowicjuszem w zakresie programowania funkcjonalnego, więc niektóre problemy wydają się trudniejsze do rozwiązania za pomocą podejścia funkcjonalnego.Noś informacje o poprzednich obliczeniach
Załóżmy, że mam listę liczb, na przykład od 1 do 10 000, i chcę uzyskać pozycje listy, które sumują się do co najwyżej liczby n (powiedzmy 100). Tak więc otrzymywałby liczby, dopóki ich suma nie przekroczy 100.
W programowaniu imperatywnym, jest to dość trywialne, aby rozwiązać ten problem, ponieważ mogę zachować zmienną w każdej interakcji i zatrzymać się, gdy cel zostanie osiągnięty.
Ale jak mogę zrobić to samo w programowaniu funkcjonalnym? Ponieważ funkcja sumowania działa na zakończonych listach, a ja wciąż nie mam ukończonej listy, jak mogę "kontynuować" obliczenia?
Jeśli suma leniwie komputerowej, mogę napisać coś takiego:
(1 to 10000).sum.takeWhile(_ < 100)
PS: Chociaż każda odpowiedź będzie mile widziane, chciałbym taki, który nie obliczyć sumę za każdym razem, ponieważ oczywiście wersja imperatywna będzie znacznie bardziej optymalna pod względem prędkości.
Edit:
wiem, że mogę „przerobić” podejście pętli koniecznie funkcjonalnego funkcji rekurencyjnej. Jestem bardziej zainteresowany znalezieniem, czy jedna z istniejących funkcji bibliotecznych może zapewnić mi możliwość nie pisania jej za każdym razem, gdy czegoś potrzebuję.
Prawdopodobnie najłatwiejszy w użyciu zmienny akumulator. '{var sum = 0; (Od 1 do 10000) takeWhile {i => sum + = i; suma <100}} '. Nic złego w tym, że mamy 'var' tutaj; nie może uciec, ponieważ wyrażenie ma wokół niego wartość {{}. –
Dlaczego uważasz, że pisanie funkcji "za każdym razem, gdy czegoś potrzebujesz" jest mniej naturalne niż pisanie imperatywnej pętli za każdym razem, gdy czegoś potrzebujesz? – Ben