在列表monad中使用return和not使用return [英] Using return vs. not using return in the list monad

查看:118
本文介绍了在列表monad中使用return和not使用return的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始了我的大赫斯格尔远征(GHC :)),我对单子和IO功能有些困惑。任何人都可以简单地解释 这两个函数有什么不同?

  f1 = do x < -  [1,2] 
[x,x + 1] - 这是monad,对吗?

f2 = do x < - [1,2]
return [x,x + 1]

结果如下:

  *主要> f1 
[1,2,2,3]

*主要> f2
[[1,2],[2,3]]


解决方案

这里的其他答案是正确的,但我不知道他们是不是你需要的东西...我会尽量保持这个尽可能简单,只有两点:






要点1. return 不是特别的东西在Haskell语言中。这不是关键字,它不是其他语言的语法糖。这只是一个函数,它是 Monad typeclass的一部分。它的签名很简单:

  return :: a  - > ma 

其中 m 在当时重谈。它需要一个纯粹的价值,并将其堵塞到你的monad中。 (顺便说一句,还有另一个称为 pure 的函数,它基本上是 return 的同义词......我更喜欢它,因为名称)无论如何,如果 m 是列表monad,那么 return 具有这种类型:

  return :: a  - > [a] 

如果有帮助,您可以考虑类型同义词类型列表a = [a] ,这可能使得它稍微更加明显: List 是我们替代的东西。无论如何,如果你打算自己实现 return ,那么你实现它的唯一合理的方法是通过获取一些值(无论类型 a )并将其粘贴在列表中:

  return a = [a] 

所以我可以在列表monad中说返回1 ,并且我会得到 [1] 。我同样可以说 return [1,2,3] ,我会得到 [[1,2,3]]






要点2. IO 是一个monad,但不是所有monad都是 IO 许多Haskell教程似乎将这两个主题混为一谈主要是出于历史原因(顺便说一句,同样令人困惑的历史原因导致至 return 的命名如此糟糕)。这听起来像你可能会有一些(可以理解的)困惑。



在你的代码中,你是在列表monad中的,因为你写了 do x < - [1,2] 。例如,如果你写了 do x< - getLine ,你会在 IO monad(因为 getLine 返回 IO字符串)。无论如何,你在monad列表中,所以你得到了上面描述的 return 的列表定义。您还可以获得>> = 的列表定义,它仅仅是(<翻译后的版本) concatMap ,已定义as:

  concatMap ::(a  - > [b]) - > [a]  - > [b] 
concatMap f xs = concat(map f xs)

其他发布的答案几乎没有从这里覆盖:)我知道我没有直接回答你的问题,但我希望这两点,而不是解决你可能会发现混淆基本的东西。


I started my Grand Haskell Crusade (GHC :) ) and I am a bit confused with monads and IO functions. Could anyone explain simply what is the difference between those two functions?

f1 = do x <- [1,2]
        [x, x+1] -- this is monad, right?

f2 = do x <- [1,2]
        return [x, x+1]

The results are:

*Main> f1
[1,2,2,3]

*Main> f2
[[1,2],[2,3]]

解决方案

The other answers here are correct, but I wonder if they're not quite what you need... I'll try to keep this as simple as possible, just two points:


Point 1. return is not a special thing in the Haskell language. It's not a keyword, and it's not syntactic sugar for something else. It's just a function that's part of the Monad typeclass. Its signature is simply:

return :: a -> m a

where m is whichever monad we're talking about at the time. It takes a "pure" value and jams it into your monad. (Incidentally, there's another function called pure that's basically a synonym for return... I like it better because the name is more obvious!) Anyway, if m is the list monad, then return has this type:

return :: a -> [a]

If it helps, you could think of the type synonym type List a = [a], which might make it slightly more obvious that List is the thing we're substituting for m. Anyway, if you were going to implement return yourself, the only reasonable way you'd implement it is by taking some value (of whatever type a) and sticking it in a list by itself:

return a = [a]

So I can say return 1 in the list monad, and I'll get [1]. I can likewise say return [1, 2, 3] and I'll get [[1, 2, 3]].


Point 2. IO is a monad, but not all monads are IO. Many Haskell tutorials seem to conflate the two topics largely for historical reasons (incidentally, the same confusing historical reasons that led to return being so poorly named). It sounds like you might have some (understandable) confusion around that.

In your code, you're in the list monad because you wrote do x <- [1, 2]. If instead you had written do x <- getLine for example, you'd be in the IO monad (because getLine returns IO String). Anyway, you're in the list monad, so you get list's definition of return described above. You also get list's definition of >>=, which is just (a flipped version of) concatMap, defined as:

concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f xs = concat (map f xs)

The other posted answers pretty much have it covered from here :) I know I didn't answer your question directly, but I'm hoping these two points instead addressed the fundamental things you might have found confusing.

这篇关于在列表monad中使用return和not使用return的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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