Question

Je suis en train de faire ce qui doit être évidentes en Haskell, qui est d'aller d' Just [1] et Just [2] pour Just [1, 2].Cependant je ne peux pas trouver quelque chose en ligne que je continue de trouver un lien mais inutile pages.Alors, comment voulez-vous accomplir cela?

Était-ce utile?

La solution

Vous pouvez utiliser liftA2 (++):

liftA2 (++) :: Maybe [a] -> Maybe [a] -> Maybe [a]

liftA2 juste des ascenseurs une fonction binaire dans un Applicative. Applicatives ont été conçus pour le levage de fonctions arbitraires d'arguments dans un contexte, donc ils sont parfaits pour cela.Dans ce cas, l' Applicative nous utilisons est Maybe.Pour voir comment cela fonctionne, nous pouvons regarder la définition:

liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = f <$> a <*> b

(<$>) juste ascenseurs toute fonction sur de pures valeurs de fonctionnement à l'intérieur de f: (a -> b) -> f a -> f b.(C'est juste un alias pour fmap, si vous êtes familier avec Functors). Pour Maybe:

_ <$> Nothing = Nothing
f <$> Just x = Just (f x)

(<*>) c'est un peu plus compliqué:il applique une fonction à l'intérieur de f pour une valeur à l'intérieur f: f (a -> b) -> f a -> f b.Pour Maybe:

Just f <*> Just x = Just (f x)
_ <*> _ = Nothing

(En fait, f <$> x c'est la même chose que pure f <*> x, qui est Just f <*> x pour Maybe.)

Donc, on peut étendre la définition de l' liftA2 (++):

liftA2 (++) a b = (++) <$> a <*> b

-- expand (<$>)
liftA2 (++) (Just xs) b = Just (xs ++) <*> b
liftA2 (++) _ _ = Nothing

-- expand (<*>)
liftA2 (++) (Just xs) (Just ys) = Just (xs ++ ys)
liftA2 (++) _ _ = Nothing

En effet, nous pouvons utiliser ces opérateurs pour soulever une fonction de tout nombre d'arguments dans n'importe quel Applicative, juste en suivant le schéma de liftA2.Ceci est appelé applicative style, et est très commun dans idiomatiques du code Haskell.Dans ce cas, il pourrait même être plus idiomatique de l'utiliser directement en écrivant (++) <$> a <*> b, si a et b sont déjà variables.(D'un autre côté, si vous êtes partiellement l'application il — dire, de les transmettre à une fonction d'ordre supérieur — puis liftA2 (++) est préférable.)

Chaque Monad est un Applicative, donc si jamais vous vous trouvez en essayant de "lever" une fonction dans un contexte, Applicative est probablement ce que vous cherchez.

Autres conseils

Pour étendre la solution à une liste de Justs, vous pouvez utiliser

fmap join $ sequence [Just[1],Just[2],Just[3]]
-- Just [1,2,3]

alors que @ehird la réponse est génial, je l'aurais utilisé une noobish solution sous la forme:

mergeJust a b = do
    a' <- a
    b' <- b
    return (a' ++ b')

Depuis, il n'a pas été mentionné dans d'autres solutions, je vais le dire ici.La façon la plus simple pour accomplir votre tâche, à mon avis, est d'utiliser un <> (ou mappend) de Data.Monoid.

import Data.Monoid

Just [1,2] <> Just [7,8] == Just [1,2,7,8]

Toutefois, notez que cette solution, contrairement à ehird de la solution applicative, ne seront pas court-circuit sur Nothing des valeurs.

Just [1,2] <> Nothing ---> Just [1,2]
--However
(++) <$> Just [1,2] <*> Nothing ---> Nothing
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top