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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.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 - Fatal编程技术网

Haskell绑定到变量与内联声明

Haskell绑定到变量与内联声明,haskell,Haskell,我是Haskell的新手,正在编写一个从JSON到其他格式的编译器。我不理解将表达式绑定到变量与将其内联传递之间的区别,这里有两个示例(在do块中),我希望它们的工作原理相同,但第二个示例混淆了typechecker并失败: 工作如期进行 modul <- parseModule <$> readFile "foo.json" case (modul) of (Left s) -> error s (Right m) -> what

我是Haskell的新手,正在编写一个从JSON到其他格式的编译器。我不理解将表达式绑定到变量与将其内联传递之间的区别,这里有两个示例(在
do
块中),我希望它们的工作原理相同,但第二个示例混淆了typechecker并失败:

工作如期进行

modul <- parseModule <$> readFile "foo.json"
case (modul) of
        (Left s) -> error s
        (Right m) -> what (m :: Module) `shouldBe` "module"
parseModule readFile“foo.json”
不是可以进行模式匹配的值。该值不是纯功能性的,因为它依赖于真实世界的资源(文件)

相反,它是一个IO操作,在执行时能够获得值(然后它拍摄“世界状态的快照,冻结为纯值”)

实际上,执行IO操作只有一种方法:将它们分配给名称
main
,编译并运行。这听起来可能有点疯狂——一个程序中只能有一个操作但事实并非如此,因为您可以将多个操作(按顺序执行)组合成一个操作并执行该操作。这种动作的组合是通过单子的概念来完成的。在您的例子中,您基本上希望使用类型为
任意字符串模块->IO()
的函数来编写类型为
IO(任意字符串模块)
的操作。这就是为什么

main::IO()
main=parseModule读取文件“foo.json”>>=f
式中,f模=……的情况模。。。
…或以lambda风格

main = parseModule <$> readFile "foo.json"
      >>= \modul -> case modul of
            Left s  -> error s
            Right m -> what m `shouldBe` "module"
main=parseModule读取文件“foo.json”
>>=\modul->case modul of
左s->错误s
右键m->m`应该是什么“模块”
由于经常需要这种绑定,Haskell为其提供了特殊的
do
语法,您已经在第一个代码段中使用了这种语法。它只是这个
>=
操作符链的语法糖,但一元绑定是必不可少的。

parseModule readFile“foo.json”
不是一个可以进行模式匹配的值。该值不是纯功能性的,因为它依赖于真实世界的资源(文件)

相反,它是一个IO操作,在执行时能够获得值(然后它拍摄“世界状态的快照,冻结为纯值”)

实际上,执行IO操作只有一种方法:将它们分配给名称
main
,编译并运行。这听起来可能有点疯狂——一个程序中只能有一个操作但事实并非如此,因为您可以将多个操作(按顺序执行)组合成一个操作并执行该操作。这种动作的组合是通过单子的概念来完成的。在您的例子中,您基本上希望使用类型为
任意字符串模块->IO()
的函数来编写类型为
IO(任意字符串模块)
的操作。这就是为什么

main::IO()
main=parseModule读取文件“foo.json”>>=f
式中,f模=……的情况模。。。
…或以lambda风格

main = parseModule <$> readFile "foo.json"
      >>= \modul -> case modul of
            Left s  -> error s
            Right m -> what m `shouldBe` "module"
main=parseModule读取文件“foo.json”
>>=\modul->case modul of
左s->错误s
右键m->m`应该是什么“模块”

由于经常需要这种绑定,Haskell为其提供了特殊的
do
语法,您已经在第一个代码段中使用了这种语法。它只是这个
>=
操作符链的语法糖,但一元绑定是必不可少的。

错误消息通常非常明确地说明预期类型和实际类型。重要的细节是
你能试试下面的
案例模块吗谢谢,我在问题中添加了错误@epsilonhalbe看起来您是正确的,错误与天气有关
parseModule readFile“foo.json”
是早评估还是晚评估的。我可以使用像
seq
这样的东西吗?或者绑定到
modul
是内联的唯一方法吗?@epsilonhalbe我从未见过
我在使用ghc 7.x的代码库中看到过这种语法,所以它一定存在了一段时间。我猜它不起作用是因为ghci或更新的ghc。也许我应该添加一个免责声明,我不建议使用这种语法,尽管我认为这是有效的,但它确实会混淆错误消息通常非常明确地说明预期的类型和实际的类型。重要的细节是
你能试试下面的
案例模块吗谢谢,我在问题中添加了错误@epsilonhalbe看起来您是正确的,错误与天气有关
parseModule readFile“foo.json”
是早评估还是晚评估的。我可以使用像
seq
这样的东西吗?或者绑定到
modul
是内联的唯一方法吗?@epsilonhalbe我从未见过
我在使用ghc 7.x的代码库中看到过这种语法,所以它一定存在了一段时间。我猜它不起作用是因为ghci或更新的ghc。也许我应该加上一个免责声明,我不建议使用这种语法,虽然我认为这是有效的,但它确实令人困惑伟大的答案,谢谢!因此,我猜
do
语法:
do{x>=f
?而且,在这两种情况下,expr()都被计算并绑定到一个结果,而不是传递thunk?@rausted在sugar点上完全正确。给出了sugar的详细信息。至于关于“evaluated and not a thunk”的注释:否,该注释偏离目标。“已评估”(thunk ness)和“已执行”(实际输入/输出已完成)是独立的概念;一个动作可以从一个thunk转换为一个被评估的对象,而不必执行。@rausted当某个对象被评估时,实际上什么都不会发生,除了处理器可能会从预先计算为正常形式的局部常数中得到温暖。对于任何给定的Haskell值,评估只会发生一次(重新使用已评估的值时)
main :: IO ()
main = parseModule <$> readFile "foo.json" >>= f
 where f modul = case modul of ...
main = parseModule <$> readFile "foo.json"
      >>= \modul -> case modul of
            Left s  -> error s
            Right m -> what m `shouldBe` "module"