gpt4 book ai didi

Scala 相当于 Haskell 的 do-notation(又一次)

转载 作者:行者123 更新时间:2023-12-03 12:13:26 25 4
gpt4 key购买 nike

我知道 Haskell 的

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

可以在 Scala 中表示为
for {
x <- List(1, 2, 3)
y <- List(7, 8, 9)
z = x + y
} yield z

但是,特别是对于 monad,Haskell 经常在 do 中包含语句。不对应 <- 的 block 或 = .例如,下面是 Pandoc 的一些代码,它使用 Parsec 从字符串中解析某些内容。
-- | 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

如您所见,它保存位置和输入,在字符串上运行解析器,然后在返回结果之前恢复输入和位置。

我这辈子都不知道怎么翻译 setInput str , setInput oldInput , 和 setPosition oldPos进入斯卡拉。我认为如果我只是把无意义的变量放进去,这样我就可以使用 <- , 喜欢
for {
oldPos <- getPosition
oldInput <- getInput
whyAmIHere <- setInput str
result <- parser
...
} yield result

但我不确定情况是否如此,如果它是正确的,我相信一定有更好的方法来做到这一点。

哦,如果你能回答这个问题,你能再回答一个吗:我必须盯着 Monads 多长时间才能感觉它们不像黑魔法? :-)

谢谢!
托德

最佳答案

是的,那个翻译是有效的。
do { x <- m; n }相当于m >>= \x -> n , 和 do { m; n }相当于m >> n .由于m >> n定义为 m >>= \_ -> n (其中 _ 的意思是“不要将此值绑定(bind)到任何东西”),这确实是一个有效的翻译; do { m; n }do { _ <- m; n } 相同, 或 do { unusedVariable <- m; n } .
do 中没有变量绑定(bind)的语句block 只是忽略结果,通常是因为没有有意义的结果可言。例如,putStrLn "Hello, world!" 的结果没有什么有趣的地方。 ,因此您不会将其结果绑定(bind)到变量。

(至于 monad 是黑魔法,你能得到的最好的认识是它们一点也不复杂;试图在它们中找到更深层次的含义通常不是学习它们如何工作的有效方式。它们只是一个接口(interface)编写碰巧特别常见的计算。我建议阅读 Typeclassopedia 以牢牢掌握 Haskell 的抽象类型类,尽管您需要阅读一般的 Haskell 介绍才能从中获得更多信息。)

关于Scala 相当于 Haskell 的 do-notation(又一次),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10441559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com