斯卡拉等同于哈斯克尔的符号(再次) [英] Scala equivalent of Haskell's do-notation (yet again)

查看:139
本文介绍了斯卡拉等同于哈斯克尔的符号(再次)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道Haskell的

  do 
x< - [1,2,3]
y < - [7,8,9]
让z =(x + y)
返回z

可以用Scala表示为:
$ b $ pre $ 对于{
x< - List(1, 2,3)
y< - List(7,8,9)
z = x + y
}产生z

但是,特别是对于monad,Haskell经常在 do 块中有语句,它们不对应< - = 。例如,下面是Pandoc的一些代码,它使用Parsec来解析字符串中的某些内容。

   -  |使用解析器解析'str'的内容并返回结果。 
parseFromString :: GenParser tok st a - > [tok] - > GenParser tok st a
parseFromString解析器str = do
oldPos< - getPosition
oldInput< - getInput
setInput str
结果< - 解析器
setInput oldInput
setPosition oldPos
返回结果

正如您所看到的,它可以节省位置和输入,在字符串上运行解析器,然后在返回结果之前恢复输入和位置。



我不能为我的生活弄清楚如何翻译 setInput str setInput oldInput setPosition oldPos 进入Scala。我认为这将工作,如果我只是把无意义的变量,所以我可以使用< - ,如



<$ p $对于{
oldPos< - getPosition
oldInput< - getInput
whyAmIHere< - setInput str
result< - 解析器
...
}收益结果

但我不确定情况如何,如果它是正确的,我相信必须有更好的方式来做到这一点。



哦,如果你能回答这个问题,你能回答一个问题吗?更多:在他们不喜欢黑魔法之前,我必须盯着Monad多久? : - )



谢谢!
Todd

解决方案

是的,那个翻译是有效的。

do {x < - m; n} 相当于 m>> = \ x - > n do {m; n} 相当于 m>> Ñ。由于 m>> n 定义为 m>> = \ _ - > n (其中 _ 表示不要将此值绑定到任何东西),这确实是一个有效的翻译; do {m; n} do {_< - m; n} do {unusedVariable < - m;

do 块中没有变量绑定的语句简单地忽略结果通常是因为没有有意义的结果可言。例如,对 putStrLnHello,world!的结果没有任何意义,所以你不会将它的结果绑定到一个变量上。



(对于monads来说,黑魔法是最好的认识,他们根本不是很复杂;试图找到更深层次的意义通常不是一种有效的学习方式它们是如何工作的,它们只是一个接口,用于组合计算,而这些计算恰好是非常常见的,我建议阅读 Typeclassopedia 对Haskell的抽象类型类很好掌握,尽管你需要阅读一般的Haskell介绍才能从中获得更多。)


I know that Haskell's

do
  x <- [1, 2, 3]
  y <- [7, 8, 9]
  let z = (x + y)
  return z

can be expressed in Scala as

for {
  x <- List(1, 2, 3)
  y <- List(7, 8, 9)
  z = x + y
} yield z

But, especially with monads, Haskell often has statements inside the do block that don't correspond to either <- or =. For example, here's some code from Pandoc that uses Parsec to parse something from a string.

-- | Parse contents of 'str' using 'parser' and return result.
parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a
parseFromString parser str = do
  oldPos <- getPosition
  oldInput <- getInput
  setInput str
  result <- parser
  setInput oldInput
  setPosition oldPos
  return result

As you can see, it saves the position and input, runs the parser on the string, and then restores the input and position before returning the result.

I can't for the life of me figure out how to translate setInput str, setInput oldInput, and setPosition oldPos into Scala. I think it would work if I just put nonsense variables in so I could use <-, like

for {
  oldPos <- getPosition
  oldInput <- getInput
  whyAmIHere <- setInput str
  result <- parser
  ...
} yield result

but I'm not sure that's the case and, if it is correct, I'm sure that there must be a better way to do this.

Oh, and if you can answer this question, can you answer one more: how long do I have to stare at Monads before they don't feel like black magic? :-)

Thanks! Todd

解决方案

Yes, that translation is valid.

do { x <- m; n } is equivalent to m >>= \x -> n, and do { m; n } is equivalent to m >> n. Since m >> n is defined as m >>= \_ -> n (where _ means "don't bind this value to anything"), that is indeed a valid translation; do { m; n } is the same as do { _ <- m; n }, or do { unusedVariable <- m; n }.

A statement without a variable binding in a do block simply disregards the result, usually because there's no meaningful result to speak of. For instance, there's nothing interesting to do with the result of putStrLn "Hello, world!", so you wouldn't bind its result to a variable.

(As for monads being black magic, the best realisation you can have is that they're not really complicated at all; trying to find deeper meaning in them is not generally a productive way of learning how they work. They're simply an interface to compose computations that happen to be particularly common. I recommend reading the Typeclassopedia to get a solid grasp on Haskell's abstract typeclasses, though you'll need to have read a general Haskell introduction to get much out of it.)

这篇关于斯卡拉等同于哈斯克尔的符号(再次)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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