“ <-”是什么意思?

玛格纳·克莱普(Magnar Kleppe)

在本教程http://learnyouahaskell.com/starting-out中,作者编写了这段代码。

boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

然后像这样执行它

boomBangs[7..13]

我的问题是,“ <-”运算符的作用是什么?在我看来,这似乎会导致递归行为,因为我是在引用一个看起来像函数内部的函数的东西,或者可能是定义如何创建列表推导。

到处搜寻,我在另一个不同的问题上找到了chi的解释
“ x <-操作运行IO操作,获取其结果,并将其绑定到x”

上面链接的问题中的“ <-”与我上面复制的代码中使用的“ <-”是否不同?xs是否在xs内运行?如果有人可以向我解释一下这件事,我将不胜感激。

威廉·范昂塞姆

您的列表理解实质上就是以下方面的语法糖:

import Control.Monad(guard)

boomBangs :: Integral i => [i] -> [String]
boomBangs xs = do
    x <- xs
    guard (odd x)
    return (if x < 10 then "BOOM!" else "BANG!")

因此,这是一种do表达[Haskell报告],并且正如该报告所说,它是语法糖。它是用于以下方面的语法糖:

boomBangs xs = xs >>= \x -> (guard (odd x) >> return (if x < 10 then "BOOM!" else "BANG!"))

对于列表,Monad实例定义为:

instance Monad [] where
    (>>=) = flip concatMap
    return x = [x]

此外,guard定义为:

guard :: Monad m => Bool -> m ()
guard True = pure ()
guard False = empty

的默认实现(>>)是:

(>>) :: Monad m => m a -> m b -> m b
(>>) u v = u >>= \_ -> v

因此,boomBangs基本上实现为:

boomBangs xs = concatMap (\x -> (guard (odd x) >>= \_ -> [if x < 10 then "BOOM!" else "BANG!"])) xs
             = concatMap (\x -> concatMap (\_ -> [if x < 10 then "BOOM!" else "BANG!"]) guard (odd x)) xs

由于可以获取列表,因此guard可以专门用于:

-- guard for the Monad []
guard :: Bool -> [()]
guard True = [()]
guard False = []

因此,这意味着,如果guard得到a True,它将返回一个单例列表,并返回False一个空列表。因此,这意味着给定防护措施后,concatMap (\_ -> [if x < 10 then "BOOM!" else "BANG!"])会返回中的内容[if x < 10 then "BOOM!" else "BANG!"],如果防护措施失败,它将返回一个空列表。因此,防护罩充当某种过滤器。

那么,现在是什么x <-如果我们看一下如何将do-expressions删除,anx <- foo对应于foo >>= \x -> ...

对于列表理解,它x <- ...充当某种“枚举器”:它将枚举列表中的所有元素,并且x每次都会获取列表中的元素之一以进行进一步处理。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章