使用monads处理列表操作等简单的任务? [英] Using monads for trivial tasks like list manipulation?

查看:108
本文介绍了使用monads处理列表操作等简单的任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



有没有任何monads可以做列表操作的例子,有人可以提供这些例子吗?每当我读到Monad的例子时,他们总是将IO作为案例研究。我认为这可能是过度杀伤,但我有兴趣,如果monad可以提供优于常规列表操作技术。

解决方案

到Haskell中的单子monad列表的解析是句法糖的do块。任何时候你写一个列表理解,你都可以写一个do块来代替,它使用列表monad实例。



一个简单的例子



假设您想要取两个列表,并返回它们的笛卡尔积(对于每个列表返回(x,y))第一个列表中的 x 和第二个列表中的 y )。

你可以用列表理解来做到这一点:

  ghci> [(x,y)| x  -  [1,2],y  -  [3,4]]  -  [(1,3),(1,4),(2,3),(2,4)] 

列表理解是这个do块的语法糖:

< $ p $ zs = do x < - [1,2]
y< - [3,4]
return(x,y)

这反过来又是语法糖

  zs = [1,2]>> = \ x  - > [3,4]>> = \ y  - >返回(x,y)



一个更复杂的例子



然而,这个例子并没有真正展示monad的强大功能,因为你可以很容易地编写它,而不依赖于列表具有Monad实例的事实。例如,如果我们只使用Applicative实例:

  ghci> import Control.Applicative 
ghci> (,)< $> [1,2] *< [3,4] - [(1,3),(1,4),(2,3),(2,4)]

现在让我们假设您将正整数列表中的每个元素都取出并复制它自身的次数(例如 f [1,2,3] = [1,2,2,3,3,3] 例如)。谁知道你为什么想这样做,但很简单:

  ghci>让f xs = [y | x < -  xs,y < -  replicate x x] 
ghci> f [1,2,3] - [1,2,2,3,3,3]



<这只是语法上的糖:

  f xs = do x < -  xs 
y< - replicate xx
返回y

这反过来又是$ b $的语法糖b

  f xs = xs>> = \ x  - >复制x x>> = \ y  - >返回y 

这次我们不能写出只使用应用程序实例。主要区别在于我们从第一个绑定( x )输出,并使块的其余部分依赖于它( y< - 复制xx )。


Whenever I read about Monad example, they always present IO as a case study.

Are there any examples of monads doing list manipulation which somebody could present? I aprpeciate this could be overkill, but I am interested if monads can present advantages over regular list manipulation techniques.

解决方案

The big secret to the list monad in Haskell is that list comprehensions are syntactic sugar for do blocks. Any time you write a list comprehension, you could have written it using a do block instead, which uses the list monad instance.

A simple example

Let's say you want to take two lists, and return their cartesian product (that is, the list of (x,y) for every combination of x from the first list and y from the second list).

You can do that with a list comprehension:

ghci> [(x,y) | x <- [1,2], y <- [3,4]] -- [(1,3),(1,4),(2,3),(2,4)]

The list comprehension is syntactic sugar for this do block:

zs = do x <- [1,2]
        y <- [3,4]
        return (x,y)

which in turn is syntactic sugar for

zs = [1,2] >>= \x -> [3,4] >>= \y -> return (x,y)

A more complicated example

That example doesn't really demonstrate the power of monads, though, because you could easily write it without relying on the fact that lists have a Monad instance. For example, if we only use the Applicative instance:

ghci> import Control.Applicative
ghci> (,) <$> [1,2] <*> [3,4] -- [(1,3),(1,4),(2,3),(2,4)]

Now let's say you take every element of a list of positive integers, and replicate it as many times as itself (so e.g. f [1,2,3] = [1,2,2,3,3,3] for example). Who knows why you'd want to do that, but it is easy:

ghci> let f xs = [ y | x <- xs, y <- replicate x x ]
ghci> f [1,2,3] -- [1,2,2,3,3,3]

That's just syntactic sugar for this:

f xs = do x <- xs
          y <- replicate x x
          return y

which in turn is syntactic sugar for

f xs = xs >>= \x -> replicate x x >>= \y -> return y

This time we can't write that just using the applicative instance. The key difference is that we took the output from the first bind (x) and made the rest of the block depend on it (y <- replicate x x).

这篇关于使用monads处理列表操作等简单的任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆