0

我有一些功能

bar :: MyType -> MyType -> [MyType]

我想要另一个功能:

foo :: [MyType] -> [MyType]
foo xs = do x <- xs
            y <- xs
            bar x y

foo不使用do符号可以写吗?我在想类似的东西,liftA2但那行不通。

4

2 回答 2

8

我们可以使用来自 do-blocks 的算法转换,如Haskell 报告中所述:

foo :: [MType] -> [MType]
foo xs = xs >>= \x -> xs >>= \y -> bar x y

y但是我们可以通过省略变量来减少 lambda 表达式的数量:

foo :: [MType] -> [MType]
foo xs = xs >>= \x -> xs >>= bar x

我们也可以省略x变量,\x -> xs >>= bar x写成(xs >>=) . bar

foo :: [MType] -> [MType]
foo xs = xs >>= ((xs >>=) . bar)

或者像@M.Aroosi所说,我们可以使用join :: Monad m => m (m a) -> m aand的组合liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

foo :: [MType] -> [MType]
foo xs = join (liftA2 bar xs xs)
于 2018-09-06T20:49:52.273 回答
2

您还可以将以下模式用于不同的元数bar

阿里蒂 2

-- bar :: [MType] -> [MType]
foo :: [MType] -> [MType]
foo xs = join $ bar <$> xs <*> xs

阿里蒂 3

-- bar :: [MType] -> [MType] -> [MType]
foo :: [MType] -> [MType]
foo xs = join $ bar <$> xs <*> xs <*> xs

等等。

我喜欢这个,因为它比硬编码更容易扩展liftA2

于 2018-09-07T11:46:12.483 回答