为什么 haskell 尝试将字符串添加到此字符串的末尾时停止?

Why does haskell stop when trying to add a string to the end of this string?

我正在尝试将字符串添加到 Haskell 中的字符串末尾。

    albumStr = ""
main = do
 let albumStr = albumStr ++ "nothing"
 print albumStr

每当我 运行 这个它就卡住了 “ 在控制台中,我必须终止它。

为什么?以及如何以这种方式将一个字符串添加到另一个字符串?

编辑: 如何将多个字符串添加到当前字符串的末尾而不覆盖它。

谢谢

等式

albumStr = albumStr ++ "nothing"

递归定义一个字符串,根本不使用全局定义的albumStr。递归立即挂起(类似于无限循环)。

打开警告会报告全局名称的阴影。

如果您不想递归定义,请使用另一个变量名:

albumStr2 = albumStr ++ "nothing"

与 ML 不同,Haskell 没有 rec 关键字来标记递归定义。相反,所有定义都可以递归,这意味着在每个变量定义中,定义的变量在其定义期间已经在范围内。

所以在let albumStr = albumStr ++ "nothing"中,=右边的albumStr指的是=左边定义的那个——不是定义在=的那个第 1 行。因此该定义是无限递归的并且永远循环。

如果你想定义一个基于另一个变量的变量,你必须给它一个不同的名字:

let localAlbumStr = albumStr ++ "nothing"

do表示法,可以写成

do { albumStr <- pure (albumStr ++ "nothing") 
   ; ... 
   } 

它会(似乎)起作用。

虽然 let(和函数)绑定在 Haskell 中是递归的,但 do 绑定不是。

而是自动创建一个阴影变量,它实际上是一个同名的新变量。 <- 右侧的代码位于绑定上方的范围内; <- 左侧的代码在一个新的、更广泛的范围内(包括较早的范围)。

另请参阅:

  • how to increment a variable in functional programming