当我使用JS时,我有两个选项来处理函数。
var a = function() {};
var b = a; // b is the function a itself.
var c = a(); // c is result of the evaluation of function a.
AFAIK,Haskell默认是懒惰的,所以默认情况下我总是得到b
。但如果我想获得c
,我该怎么办?
我想我应该明确一词。
我在ghci
做了类似的事情。
let a = getLine
a
我想将getLine
的结果导入a
。
我注意到此代码供以后像我这样的人参考。
我可以用@ Ankur的帮助纠正Haskell的翻译。
上面的代码示例不是很好,因为函数a
不会返回任何内容。
如果我这样改变它;
var a = function(x,y) { return x * y; };
var b = a; // b is the function a itself.
var c = a(); // c is result of the evaluation of function a.
翻译成Haskell会变成这样。
let a = \ x y -> x* y // Anonymous lambda function.
let b = a
let c = a 100 200
答案 0 :(得分:2)
您的JS代码将转换为Haskell:
Prelude> let a = (\() -> ())
Prelude> let b = a
Prelude> let c = a()
你的JS函数没有任何东西(你可以建模为()类型)并且没有返回任何内容,即()
getLine
是IO String
类型的值,因此,如果您说let a = getLine
,a
将成为IO String
类型的值。你想要的是从String
中提取IO String
,可以这样做:
a <- getLine
答案 1 :(得分:0)
请注意,与Javascript的并行不太正确 - 例如,假设a
返回一个数字,b + b
在Haskell中有意义但在您的示例Javascript中没有意义。原则上Haskell中的函数只是一个参数的函数 - 看起来是两个参数的函数是一个参数的函数,它返回一个参数的函数,返回一个值。 Haskell中的b
不是一个未经评估的“零参数函数”,而是一个未评估的值。
为了引入严格性,你可以使用seq
,它有两个参数,第一个是严格评估的,第二个是返回的。 Read more
以下是该页面的示例,seq
用于强制立即评估z'
:
foldl' :: (a -> b -> a) -> a -> [b] -> a
foldl' _ z [] = z
foldl' f z (x:xs) = let z' = f z x in z' `seq` foldl' f z' xs
注意z'
之后再次使用的方式作为foldl'
的第二个参数,因为seq
只丢弃其第一个参数的值。
答案 2 :(得分:0)
c
的类型与返回类型匹配 - 值{ - a()
那么那将是分配给它的(不是函数本身)。c
的值,但在大多数情况下您不应该关心。为什么要提前强制进行评估?通常,在Haskell中执行此操作的唯一原因是性能。在不太纯粹的语言中,你可能会依赖于副作用,但在Haskell中不会出现这种情况 - 除非你正在使用IO monad,这样你就可以强制进行连续评估。
更新啊,所以 使用IO。