如何立即计算Haskell表达式?
当我使用JS时,我有两个选项来处理函数如何立即计算Haskell表达式?,haskell,evaluation,strict,Haskell,Evaluation,Strict,当我使用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. 好了,Haskell默认是懒惰的,所以我总是默认得到b。但是如果我想得到c,我该怎么办 更新 我想我应该明确地说一句话 我在ghci中做了类似的事情 let a = getLine a 我想让
var a = function() {};
var b = a; // b is the function a itself.
var c = a(); // c is result of the evaluation of function a.
好了,Haskell默认是懒惰的,所以我总是默认得到b
。但是如果我想得到c
,我该怎么办
更新
我想我应该明确地说一句话
我在ghci中做了类似的事情
let a = getLine
a
我想让getLine
的结果进入a
更新2
我记下这段代码,供像我这样的人以后参考。
在@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
请注意,与Javascript的并行性并不完全正确——例如,假设
a
返回一个数字,b+b
在Haskell中有意义,但在您的示例Javascript中没有意义。原则上,Haskell中的函数只包含一个参数——两个参数的函数是一个参数的函数,它返回一个参数的函数,它返回一个值seq
,它接受两个参数,第一个参数严格计算,第二个参数返回
下面是该页面的一个示例,其中使用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
仅丢弃其第一个参数的值
c
的类型与a()
的返回类型(值)相匹配,则将分配给它(而不是函数本身)c
的值,但在大多数情况下,您不应该在意更新啊,那么您正在使用 您的JS代码将转换为Haskell:
Prelude> let a = (\() -> ())
Prelude> let b = a
Prelude> let c = a()
您的JS函数没有获取任何内容(您可以将其建模为()类型),也没有返回任何内容,即再次()
getLine
是类型为IO String
的值,因此如果您说let a=getLine
,a
将成为类型为IO String
的值。您需要的是从该IO字符串
中提取字符串
,具体操作如下:
a您可能需要一个字符串,但是getline
的类型为IO string
。IO是一种特殊的盒子,你可以把东西放进去,但永远也拿不回来。您需要阅读Haskell一元I/O系统。@n.m.您可以将内容放入其中,但无法将其取回,这是不正确的。应该是这样的:你必须在框的上下文中工作,才能在框中使用值。@Ankur你是这么说的,是的。我不打算给你一个单子教程。谢谢你的讨论,但无论如何,像这样的基本例子对像我这样的初学者更有价值和帮助。我只是希望我最终能理解Monad是什么。请注意,由于在Haskell中所有函数都在,JavaScript函数function(x,y){return x*y;}
将转换为\(x,y)->x*y
。Haskell函数\xy->x*y
将是函数(x){return function(y){return x*y;}
。我从来不知道Haskell函数也可以用()
操作符调用。@Eonil:()
是Haskell中的一种类型,只有一个值,也称为()
。因为它是一个值,所以可以将它传递给接受()
类型的值的函数。如果在函数名和参数之间去掉一些空格,就会得到一种奇怪的外观,例如,id()
是id()
,这是()
。请不要混淆,()
不是运算符,而是类型(在类型签名中时)和上述用法中的值。因此a()
是应用于值()
的函数a
。