let removeLow-6ren">
gpt4 book ai didi

variables - "<-"是否意味着在 Haskell 中分配变量?

转载 作者:行者123 更新时间:2023-12-02 22:54:46 25 4
gpt4 key购买 nike

刚开始Haskell,据说Haskell中除了IO包之外的所有东西都是“不可变的”。那么当我将名称绑定(bind)到某个东西时,它总是不可变的?问题如下:

Prelude> let removeLower x=[c|c<-x, c `elem` ['A'..'Z']]
Prelude> removeLower "aseruiiUIUIdkf"
"UIUI"

所以这里:

1. “removeLower" is an immutable? Even it's a function object?
But I can still use "let" to assign something else to this name.

2. inside the function "c<-x" seems that "c" is a variable.
It is assigned by list x's values.

我使用了 C 语言中的“变量”一词,不确定 Haskell 如何命名它的所有名称?

谢谢。

最佳答案

如果您熟悉 C,请考虑声明变量和为其赋值之间的区别。例如,您可以单独声明一个变量,然后分配给它:

int i;
i = 7;

或者你可以声明一个变量并同时分配初始值:

int i = 7;

无论哪种情况,您都可以通过在第一次初始化或赋值后再次赋值来改变变量的值:

int i = 7;  // Declaration and initial assignment
i = 5; // Mutation

Haskell 中的赋值工作方式与第二个示例类似 - 带初始化的声明:

  1. 您声明一个变量;
  2. Haskell 不允许未初始化的变量,因此您需要在声明中提供一个值;
  3. 没有突变,因此声明中给出的值将是该变量在其 scope 中的唯一值。 .

我将“范围”加粗并加了超链接,因为它是这里的第二个关键组成部分。这是您的问题之一:

“removeLower" is an immutable? Even it's a function object? But I can still use "let" to assign something else to this name.

绑定(bind)后removeLower到您在示例中定义的函数,名称 removeLower将始终在该定义的范围内引用该函数。这很容易在解释器中演示。首先,我们定义一个函数foo :

Prelude> let foo x = x + 2
Prelude> foo 4
6

现在我们定义一个bar使用 foo :

Prelude> let bar x = foo (foo x)
Prelude> bar 4
8

现在我们“重新定义”foo不同的东西:

Prelude> let foo x = x + 3
Prelude> foo 4
7

现在你认为 bar 会发生什么? ?

Prelude> bar 4
8

还是一样!因为foo的“重新定义”不会改变任何东西——它只是说,在“重新定义”创建的新作用域中,名称 foo代表三相加的函数。 bar的定义是在早期范围内创建的,其中 foo x = x + 2 ,这就是名字 foo 的意思bar 的定义中有。 foo的原始值没有被“重新定义”破坏或变异。

在 Haskell 程序中和在 C 程序中一样,相同的名称仍然可以在程序的不同作用域中引用不同的值。这就是“变量”可变的原因。不同之处在于,在 Haskell 中,你永远无法在一个范围内改变变量的值。然而,您可以隐藏定义——变量的使用在某种意义上将引用该名称的“最近”定义。 (对于解释器,该变量的最新 let 声明。)

<小时/>

现在,抛开这些,下面是 Haskell 中存在的变量绑定(bind)(“赋值”)语法。首先,模块中有顶级声明:

module MyLibrary (addTwo) where

addTwo :: Int -> Int
addTwo x = x + 2

这里是名字addTwo使用给定函数作为其值进行声明。顶级声明可以在 where 中包含私有(private)辅助声明。 block :

addSquares :: Integer -> Integer
addSquares x y = squareOfX + squareOfY
where square z = z * z
squareOfX = square x
squareOfY = square y

然后是let ... in ...表达式,允许您为任何表达式声明局部变量:

addSquares :: Integer -> Integer
addSquares x y =
let square z = z * z
squareOfX = square x
squareOfY = square y
in squareOfX + squareOfY

然后是do - 具有自己的声明变量语法的符号:

example :: IO ()
example = do
putStrLn "Enter your first name:"
firstName <- getLine

putStrLn "Enter your lasst name:"
lastName <- getLine

let fullName = firstName ++ " " ++ lastName
putStrLn ("Hello, " ++ fullName ++ "!")

var <- action分配一个由操作生成的值(例如,从标准输入读取一行),而 let var = expr分配由函数生成的值(例如,连接一些字符串)。请注意 letdo block 与 let ... in ... 不同。从上面看!

最后,在列表理解中,您将获得与 do 相同的赋值语法。 - 符号。

关于variables - "<-"是否意味着在 Haskell 中分配变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35198897/

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