如果我尝试> fst(a, b)
a
,b
未定义,我会收到b
未定义的错误。即使在尝试snd(a, b)
时,b
也会导致错误。我有命令式编程的背景知识。我想知道这是否是某种我不理解的懒惰。
答案 0 :(得分:5)
我认为FUZxxl的评论绝对正确。当我输入Hugs的repl:
Hugs> fst(a,b)
ERROR - Undefined variable "b"
Hugs> snd(a,b)
ERROR - Undefined variable "b"
这不是一个懒惰/急切的评估事项 - 当Hugs检查以确保fst(a,b)
是有效的Haskell代码时,它注意到a
和b
未定义。这两个字母在Haskell中没有特殊含义,它们就像任何其他语言一样变量!
就像Java一样:
System.out.println(a);
永远不要说a
是什么!你会写一些类似的东西:
String a = "Hello world."
System.out.println(a);
要解决此问题,您可以在let语句中定义a
和b
,例如:
>let (a,b) = (1,2) in fst(a,b)
或
>let tup = (1,2) in fst tup
或
>let a=1;b=2 in fst(a,b)
或where声明
>fst(a,b) where a=1;b=2
等
或者,在一些名为whatever的文件中定义(例如,“TestTuple.hs”)
a = 1
b = 2
在Hugs中,去:
>:load TestTuple.hs
>fst(a,b)
1
虽然您注意到您正在使用Hugs,仅供参考,但在GHCi中,您还可以在REPL中定义变量,如下所示:
>let a = 1
>let b = 2
>fst(a,b)
1
>snd(a,b)
2
答案 1 :(得分:1)
以下是您将看到的内容:
Prelude> fst (undefined, undefined)
*** Exception: Prelude.undefined
Prelude> snd (undefined, undefined)
*** Exception: Prelude.undefined
如您所见,访问未定义的元素将计算为未定义的值。
懒惰允许我们避免评估整个结构,但是,
Prelude> snd (undefined, 2)
2
您的评论表明您可能忘记声明某些特定变量a
和b
。
答案 2 :(得分:0)
我认为你的问题是为什么它抱怨b而不是a,这是因为haskell任意评估参数。也就是说,你永远不知道首先评估哪一个。在你的情况下,显然,haskell在偶然之前评估b,这就是为什么它抱怨b而不是a。