Reputation: 2482
I have some function
bar :: MyType -> MyType -> [MyType]
I would like to have another function:
foo :: [MyType] -> [MyType]
foo xs = do x <- xs
y <- xs
bar x y
Is it possible to write foo
without using the do
notation? I was thinking about something like liftA2
but that won't work.
Upvotes: 1
Views: 118
Reputation: 121
You may also use the following pattern for varying arities for bar
:
Arity 2
-- bar :: [MType] -> [MType]
foo :: [MType] -> [MType]
foo xs = join $ bar <$> xs <*> xs
Arity 3
-- bar :: [MType] -> [MType] -> [MType]
foo :: [MType] -> [MType]
foo xs = join $ bar <$> xs <*> xs <*> xs
and so on.
I like this as it is easier to extend than the hardcoded liftA2
.
Upvotes: 2
Reputation: 477437
we can use the algorithmic conversion from do-blocks, as described in the Haskell report:
foo :: [MType] -> [MType]
foo xs = xs >>= \x -> xs >>= \y -> bar x y
But we can reduce the amount of lambda-expressions, by omitting the y
variable:
foo :: [MType] -> [MType]
foo xs = xs >>= \x -> xs >>= bar x
and we can omit the x
variable as well, by writing \x -> xs >>= bar x
as (xs >>=) . bar
foo :: [MType] -> [MType]
foo xs = xs >>= ((xs >>=) . bar)
Or like @M.Aroosi says, we can use a combination of join :: Monad m => m (m a) -> m a
and liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
:
foo :: [MType] -> [MType]
foo xs = join (liftA2 bar xs xs)
Upvotes: 7