是否可以在不使用 do 表示法的情况下编写此代码?



>我有一些函数

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

我想要另一个功能:

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

是否可以在不使用do表示法的情况下编写foo?我在想类似liftA2的事情,但这行不通。

我们可以使用do-block的算法转换,如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 aliftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

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

您也可以使用以下模式来为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更容易扩展。

相关内容

  • 没有找到相关文章

最新更新