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



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

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

每当我运行它时,它都会卡住"在控制台中,我必须终止它。

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

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

谢谢

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

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

如果要基于另一个变量定义变量,则必须为其指定不同的名称:

let localAlbumStr = albumStr ++ "nothing"

等式

albumStr = albumStr ++ "nothing"

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

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

如果不需要递归定义,请使用另一个变量名称:

albumStr2 = albumStr ++ "nothing"

do表示法中,你可以写

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

它(似乎(会起作用。

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

相反,会自动创建一个阴影变量,它实际上是一个具有相同名称的新变量。<-右侧的代码位于绑定上方的作用域中;<-左侧的代码位于一个新的、更广泛的范围内(包括较早的范围(。

另请参阅:

  • 如何在函数式编程中递增变量

最新更新