Sie nur zwicken und mische ein paar Worte um, wie
mit geschrieben werden können
foo (list) =
-- int somestate
-- foreach list as item
-- foreach item in list
do item <- list
if item == 1
then return incr -- state
else return decr -- state
-- return state
incr state = state + 1
decr state = state - 1
und schon holen Sie sich eine Sache, mit einem Typ daraus abgeleitet!Das ist
foo :: (Num a, Num b, Monad m, Eq a) => m a -> m (b -> b)
Wir wissen m ~ []
so ist es tatsächlich
foo :: (Num a1, Num a, Eq a) => [a] -> [b -> b]
Also, was können wir mit dem Bündel von state-Aktualisierungsfunktionen zu tun, wie incr
/decr
, in einer Reihe? Ein paar Dinge:
import Control.Monad
import Data.Monoid
import Data.Foldable
sequence . foo :: (Num a, Num b, Eq a) => [a] -> b -> [b]
foldr (.) id . foo :: (Num a, Num b, Eq a) => [a] -> b -> b
appEndo . foldMap Endo . foo
:: (Num a, Num b, Eq a) => [a] -> b -> b
foldl (.) id . foo :: (Num a, Num b, Eq a) => [a] -> b -> b
appEndo . getDual . foldMap (Dual . Endo) . foo
:: (Num a, Num b, Eq a) => [a] -> b -> b
Nicht die erste, sicherlich.
Es scheint, dass der mit foldl
das Ticket hier ist. Aber dann wieder geht es gegen nicht sunt multiplanda praeter necessitatem. Also wirklich, es ist
foo :: (Num t, Num a, Eq a) => [a] -> t -> t
foo = foldr g id
where
g x r state | x==1 = r (incr state) -- or even `r $! incr state`
| otherwise = r (decr state) -- `r $! decr state`
oder einfacher,
foo :: (Num t, Num a, Eq a) => [a] -> t -> t
foo = foldr g id
where
g x r | x==1 = r . incr
| otherwise = r . decr
oder auch nur
foo :: (Num t, Num a, Eq a) => [a] -> t -> t
foo = foldr (\x -> if x==1 then (. incr) else (. decr)) id
das ist eigentlich das mit dem Dual
wir alle zusammen hatten. Ich denke. Viel Spaß dabei, dies (oder anders) zu bestätigen. :)
Update:foldr (.) id . foo
in eine Funktion Fusing führt zu einem noch schöneren
foo :: (Num t, Num a, Eq a) => [a] -> t -> t
foo = flip $ foldr (\x -> if x==1 then incr else decr)
aber es verarbeitet den Zustand in der umgekehrten Reihenfolge.
ist es eine Falte. Was ist der Ausgangszustand? – HuStmpHrrr
Lesen Sie auch auf persistente Daten ... –
In der Regel mit 'Kopf' und' Schwanz' sind * Antipattern *: besser verwendet man hier Mustererkennung, da es sicherer und einfacher zu verstehen ist. –