Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何立即计算Haskell表达式?_Haskell_Evaluation_Strict - Fatal编程技术网

如何立即计算Haskell表达式?

如何立即计算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 我想让

当我使用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
我想让
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中的函数只包含一个参数——两个参数的函数是一个参数的函数,它返回一个参数的函数,它返回一个值b不是未赋值的“零参数函数”,而是未赋值的值

要引入严格性,可以使用
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
仅丢弃其第一个参数的值

  • 哈斯克尔不是懒惰的
  • 许多表达式都会被严格计算,请参见,因此您通常可以通过代码的结构强制严格
  • 在Haskell中,如果
    c
    的类型与
    a()
    的返回类型(值)相匹配,则将分配给它(而不是函数本身)
  • Haskell可能会推迟计算,直到您的代码实际需要
    c
    的值,但在大多数情况下,您不应该在意
  • 为什么要提前强制评估?通常,在Haskell中这样做的唯一原因是性能。在不太纯粹的语言中,您可能依赖于副作用,但在Haskell中情况并非如此-除非您使用IO monad,这样您就可以强制执行顺序求值


    更新啊,那么您正在使用

    您的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