List 在haskell中修改列表
我有一份chars的清单List 在haskell中修改列表,list,haskell,List,Haskell,我有一份chars的清单 left = ['h', 'e', 'l', 'l', 'o'] 以及功能 typer :: [Char] -> Char -> [Char] typer left c = left ++ [c] 如果我在ghci中键入typer left'a',它会返回“helloa”,但如果我尝试读取left,它会返回“hello”。“a”在哪里?是否仍然可以使用该函数操纵左侧 Haskell函数是,这意味着它们不会有诸如修改变量之类的副作用。您的typer函数根据
left = ['h', 'e', 'l', 'l', 'o']
以及功能
typer :: [Char] -> Char -> [Char]
typer left c = left ++ [c]
如果我在ghci
中键入typer left'a'
,它会返回“helloa”
,但如果我尝试读取left
,它会返回“hello”
。“a”
在哪里?是否仍然可以使用该函数操纵左侧
Haskell函数是,这意味着它们不会有诸如修改变量之类的副作用。您的typer
函数根据其参数计算结果,但它实际上不(也不能)修改其参数
作为类比,在数学中,如果n是4,那么sqrt(n)是2,但即使计算了它的平方根,n仍然是4
如果要捕获函数调用的结果以便以后使用,请将其分配给另一个变量:
right = typer left 'a'
Haskell函数是,这意味着它们不会有诸如修改变量之类的副作用。您的typer
函数根据其参数计算结果,但它实际上不(也不能)修改其参数
作为类比,在数学中,如果n是4,那么sqrt(n)是2,但即使计算了它的平方根,n仍然是4
如果要捕获函数调用的结果以便以后使用,请将其分配给另一个变量:
right = typer left 'a'
不!Haskell中的值是不可变的 您已将左侧的
声明为等于“hello”
,并且始终等于“hello”
。您可以在更近的范围内使用名为left
的新标记隐藏特定的left
值(例如具有名为left
的函数参数,这将使全局定义的left
在函数体中不可见)。但是,无法更改您声明的左
值[1]
typer
返回一个新字符串,如果要保留“helloa”
,则必须保留该值
[1] 在GHCi中,可以通过重新定义来隐藏以前的定义。这会悄悄地重新使用现有名称以指向新值。您不能在Haskell源文件中执行此操作。不!Haskell中的值是不可变的
您已将左侧的声明为等于“hello”
,并且始终等于“hello”
。您可以在更近的范围内使用名为left
的新标记隐藏特定的left
值(例如具有名为left
的函数参数,这将使全局定义的left
在函数体中不可见)。但是,无法更改您声明的左
值[1]
typer
返回一个新字符串,如果要保留“helloa”
,则必须保留该值
[1] 在GHCi中,可以通过重新定义以前的定义来隐藏它们。这会悄悄地重新使用现有名称以指向新值。不能在Haskell源文件中执行此操作。通常不可以。通常,Haskell变量是不可变的。但是,有些库包含可变变量。例如,Data.IORef
包含可更改的IORef
。我将在下面解释如何使用它们,但作为一般规则,我建议不要使用它们,而是以更实用的方式编写代码
使用IORef,可以重写函数typer
typer :: IORef [Char] -> Char -> IO()
typer left c = writeIORef left . (++[c]) =<< readIORef left
应产生所需的效果。通常不,通常情况下,Haskell变量是不可变的。但是,有些库包含可变变量。例如,Data.IORef
包含可更改的IORef
。我将在下面解释如何使用它们,但作为一般规则,我建议不要使用它们,而是以更实用的方式编写代码
使用IORef,可以重写函数typer
typer :: IORef [Char] -> Char -> IO()
typer left c = writeIORef left . (++[c]) =<< readIORef left
应该会产生所需的效果。函数返回的值不是传递给它的参数。欢迎使用haskell,其中的值是不可变的。为什么希望函数修改左侧的?例如,为什么不c
呢?函数返回的值不是传递给它的参数。欢迎来到haskell,这里的值是不可变的。为什么希望函数修改左侧的?为什么不以c
为例?关于上一条语句:您可以在do
块中使用连续的let
语句重新定义变量,这些语句隐藏了相同名称的早期定义。在这方面,GHCi REPL类似于一个大的do
块。。在
和
中,其中
在纯代码中块。对于最新的GHCi中的新手来说,这可能更令人困惑,因为绑定不再需要let
关键字,而且看起来您在REPL中执行的是常规的Haskell声明。关于您的上一条语句:您可以在do
块中使用连续的let
语句重新定义变量,隐藏相同名称的早期定义。在这方面,GHCi REPL类似于一个大的do
块。。在
和
中,其中
在纯代码中块。对于最新的GHCi中的新手来说,这可能更令人困惑,因为绑定不再需要let
关键字,而且看起来您正在REPL中执行常规的Haskell声明。