W trakcie pisania prosty kalkulator RPN, mam następujący aliasy Typ:Folding flatMap/bind na liście funkcji (aka imię To Combinator!)
type Stack = List[Double]
type Operation = Stack => Option[Stack]
... i Pisałem ciekawy wyglądający wiersz kodu Scala:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
Dzieje wstępną stack
wartości i dotyczy listę operations
do tego stosu. Każda operacja może się nie powieść (to jest uzyskać Option[Stack]
), więc sekwencjonuję je za pomocą flatMap
. Rzeczą niezwykłą w tym (moim zdaniem) jest to, że składam listę monadycznych funkcji, zamiast składać listę danych.
Chcę wiedzieć, czy istnieje standardowa funkcja, która przechwytuje to zachowanie "zwijania". Kiedy próbuję odtworzyć „nazwa, która Combinator” gra, Hoogle jest zwykle mój przyjaciel, więc próbowałem to samo ćwiczenie psychiczne w Haskell:
foldl (>>=) (Just stack) operations
Tutejsze typy:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
więc rodzaj mojej tajemnicy foldl (>>=)
Combinator, po dokonaniu rodzaje foldl
i (>>=)
line, powinno być:
mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a
... co jest znowu to, co chcemy oczekiwać. Mój problem polega na tym, że wyszukiwanie Hoogle dla funkcji z tym typem nie daje żadnych wyników. Próbowałem kilka innych permutacji, które uważałem za rozsądne: a -> [a -> m a] -> m a
(tzn. Zaczynając od wartości niemagadycznej), [a -> m a] -> m a -> m a
(tj. Z odwróconymi argumentami), ale nie ma też szczęścia. Moje pytanie brzmi, czy ktokolwiek zna standardową nazwę mojego tajemniczego kombinatora "fałd-wiązania"?
Polecam przeciwko użyciu tej implementacji kombinator; Wierzę, że większość implementacji '(>> =)' jest przeznaczona do użycia w sposób skojarzeniowy, więc istnieje duża szansa, że może to spowodować problemy z wydajnością (np. Lewostronny stos '(++)' s robi). – ehird
@ehird - Nie sądzę, że rozumiem ... Jak inaczej zaproponowałbyś zastosowanie sekwencji operacji "[a -> ma]", w kolejności od lewej do prawej, do niektórych rozpoczynających 'a' lub' ma "wartość? Pamiętaj też, że nie zadaję pytania specyficznego dla języka; charakterystyka wydajności będzie różna między Scala i Haskell (możesz założyć, że używam 'foldl'' dla ścisłości). Jedyne, na czym mi zależy, to czy ta rzecz ma dobrze znane imię. – mergeconflict
Myślę, że @ ehird wskazuje na to, że 'foldr' może być bardziej efektywny, ponieważ może się zatrzymać wcześnie (na przykład w przypadku" Nothing "). –