gpt4 book ai didi

haskell - 在 Haskell 中,为什么我需要在我的 do block 之前放一个 $?

转载 作者:行者123 更新时间:2023-12-04 01:34:09 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Why there needs to be a $ in calls like "runSomeMonad $ do ..."?

(1 个回答)


4年前关闭。




[这个问题是由“Real World Haskell”中的第9章提出的]

这是一个简单的功能(简化为基本功能):

saferOpenFile path = handle (\_ -> return Nothing) $ do
h <- openFile path ReadMode
return (Just h)

为什么我需要 $ ?

如果要处理的第二个参数不是 do block ,我不需要它。以下工作正常:
handle (\_ -> putStrLn "Error calculating result") (print x)

当我尝试删除 $编译失败。如果我明确添加括号,我可以让它工作,即
saferOpenFile path = handle (\_ -> return Nothing)  (do
h <- openFile path ReadMode
return (Just h))

我可以理解,但我想我期待当 Haskell 达到 do 时它应该认为“我正在开始一个 block ”,我们不应该明确地把 $在那里分手。

我还考虑过将 do block 推到下一行,如下所示:
saferOpenFile path = handle (\_ -> return Nothing)  
do
h <- openFile path ReadMode
return (Just h)

但是没有括号也行不通。这让我很困惑,因为以下工作:
add a b = a + b

addSeven b = add 7
b

我敢肯定,我会接受它作为“这就是你写惯用的 Haskell 的方式”,但是有没有人有任何观点可以给出?提前致谢。

最佳答案

这是由于 Haskell 的操作顺序。函数应用程序绑定(bind)最紧密,这可能会造成困惑。例如:

add a b = a + b
x = add 1 add 2 3

Haskell 将其解释为:函数 add 应用于 1,函数 add。这可能不是程序员的本意。 Haskell 会提示第二个参数需要一个 Num ,而是得到一个函数。

有两种解决方案:

1) 表达式可以用括号括起来:
x = add 1 (add 2 3)

其中 Haskell 将解释为:函数 add 应用于 1,然后 add 2 的值 3。

但是如果嵌套太深,这可能会令人困惑,因此是第二种解决方案。

2) $ 运算符:
x = add 1 $ add 2 3

$ 是一个将函数应用于其参数的运算符。 Haskell 将其解读为:函数 (add 1) 应用于 add 2 3 的值。请记住,在 Haskell 中,函数可以部分应用,因此 (add 1) 是一个完全有效的函数。

$ 运算符可以多次使用:
x = add 1 $ add 2 $ add 3 4

您选择哪种解决方案将取决于您认为在特定上下文中哪个更具可读性。

关于haskell - 在 Haskell 中,为什么我需要在我的 do block 之前放一个 $?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4911435/

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