2013-07-27 5 views
3

Je suis à la recherche de la façon idiomatique de le faire. Cela fonctionne, mais il semble que je doive réinventer quelque chose dans la bibliothèque standard. Quelle est la bonne façon de faire cela? J'essaie de transmettre une liste de fonctions et de les lier en séquence. Exemple de Toy:Novice haskell - liaison séquentielle monad

bindSeq :: (Monad m) => m a -> [(a -> m a)] -> m a 
bindSeq m [] = m 
bindSeq m (x:xs) = bindSeq (m >>= x) xs 

bindSeq (Just 4) [ Just . (+1), Just . (+2)] 
Just 7 
+6

Qu'en est-il de 'bindSeq = foldl '(>> =)'? – Fixnum

+1

Oui, c'est ce que je cherchais, merci –

+2

Voir [concatM] (http://hackage.haskell.org/packages/archive/monad-loops/latest/doc/html/Control-Monad-Loops.html #v: concatM) dans le paquet ** monad-loops **. En outre, vous pouvez définir une instance Monoid, comme [this] (https://gist.github.com/hiratara/4038651). Peut-être existe-t-il un standard déjà défini, mais je ne le trouve pas. – danidiaz

Répondre

1

Comme @Fixnum a écrit en 2013, votre bindSeq est foldl' (>>=)

Mais si vous voulez voir cela comme un « pli effectful » sur les valeurs, alors vous pouvez juste « mettre sur M- lunettes colorées "et donnez sur le m, puis regardez ce qui reste. En absence des effets monadiques, vous voulez une signature: a -> [a -> a] -> a.

Ceci est une application de fonction de pliage et peut être écrit foldl (flip ($)).

Alors maintenant, "promouvoir" que, pour être effectful et nous voyons ce qui suit:

Prelude Control.Monad> :t foldM (flip ($)) 
foldM (flip ($)) :: Monad m => a -> [a -> m a] -> m a 

comme vous le souhaitez!