Haskell函数求值

Haskell函数求值,haskell,Haskell,我对Haskell计算函数的时间和它只返回函数本身的时间比较感到困惑。我被教导模式匹配驱动功能评估,但我不明白为什么 f :: Int -> Int f x = x+1 工作。f是将1添加到整数,还是返回将1添加到整数的函数?这两个是同一件事吗?据我所知,没有模式匹配,所以我不确定为什么要对它进行评估 另一个问题:假设我想制作一个包含所有0的8x8列表,但第一行包含数字1、2、3、4、5、6、7、8。是否有任何方法可以先将其初始化为所有0,然后将第一行更改为[1..8]?我知道这样的顺序

我对Haskell计算函数的时间和它只返回函数本身的时间比较感到困惑。我被教导模式匹配驱动功能评估,但我不明白为什么

f :: Int -> Int
f x = x+1
工作。f是将1添加到整数,还是返回将1添加到整数的函数?这两个是同一件事吗?据我所知,没有模式匹配,所以我不确定为什么要对它进行评估

另一个问题:假设我想制作一个包含所有0的8x8列表,但第一行包含数字1、2、3、4、5、6、7、8。是否有任何方法可以先将其初始化为所有0,然后将第一行更改为[1..8]?我知道这样的顺序代码不是惯用的,所以有没有更好的方法来实现它,希望不用
do


最后,我还对
let
where
语法感到困惑。假设在函数定义的中间,我说<代码> TEMP= x+1 。这与说
let temp=x+1
…temp where temp=x+1
有何不同?在每种情况下,
temp
是否具有类型
Int
Int->Int
?为什么人们经常将
do
let
一起使用?

这当然是一系列问题

首先,关于评估,Haskell很懒惰。它将根据需要评估值。这包括一个事实,即一个函数不一定是完整的。在某些情况下,模式匹配可能会推动评估,例如
Nothing
Just x
必须匹配,以便找出产生的值。但是如果你一开始不要求结果,那么这个匹配就不需要了

f
在您的示例中是一个称为
(+1)
的函数,或者更明确地说是
\x->x+1
。作为一个函数,它必须应用于一个值以产生另一个值,事实上存在一种模式;参数
x
,类型为
Int
。这就像一个简单的绑定,但它可能是一个常量值模式,比如
1
。下面是一个例子:

fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
前两种模式为我们提供了基本情况

8x8数字网格是矩阵,而不是列表,并提供能够更准确地描述这些事情的类型,并且您所描述的可以完成。Ix提供了多维索引和函数,比如可以在不违反值不变性的情况下就地执行更新

让表达式中的绑定
表达式中的绑定
主要是首选项<代码>让
do
块中的绑定是另一回事。在示例绑定中,
temp=x+1
x
必须从其他地方绑定,类型为
Num a=>a->a->a
,因此
x
temp
必须是相同的
Num a
。一个函数必须有一个参数,所以这只是一个值(虽然从数学上讲它是一个
x
的函数)

至于
do
with
let
,它本质上是添加另一个绑定的缩写;你可以写:

main = do
    putStrLn "hello"
    let word = "world"
    putStrLn word
这相当于:

main = do
    putStrLn "hello"
    let word = "world" in do
        putStrLn word

这提供了一种引入纯值mid-
do
的方法,比如
我不明白你所说的“求值函数”和“返回函数”是什么意思。这似乎是3个完全不同的问题——其中一些问题(特别是第一个)表述得太模糊,无法真正回答。有几个不同的问题是好的,但是请为每个问题创建一个新的问题,而不是把无关的查询放在一个问题中。“假设在函数定义的中间,我说“代码> TEMP= x+1 ”。这是一个语法错误。在Haskell中,所有的变量都是不可变的。code>f
不能增加变量
f
只返回一个
x+1
。请不要散布危险的错误观念,认为
succ
总是与
(+1)
相同,如果两者都可用。例如,它们是不同的,并且假设它们总是相同的原因。啊,你是对的!succ将为您提供下一个可能的值,+1将增加一个单位。