Haskell中的main函数总是以main = do开头吗?

时间:2017-06-23 18:26:00

标签: haskell main do-notation

在java中我们总是写:

public static void main(String[] args){...}

当我们想开始编写程序时。

我的问题是,对于Haskell,IE是否相同:我总能确定声明: main = do,当我想在Haskell中为程序编写代码时?

例如:

main = do  
    putStrLn "What's your name?"  
    name <- getLine 
    putStrLn ("Hello " ++ name) 

该程序将询问用户“你叫什么名字?” 然后,用户输入将存储在name-variable中,并且 程序终止前将显示“Hello”++名称。

2 个答案:

答案 0 :(得分:10)

简短回答,我们必须声明main =,但 a do。< / p>

main必须是 IO monad 类型(所以IO a)其中a是任意的(因为它被忽略) ),正如here所写:

  

使用名称main很重要:main被定义为Haskell程序的入口点(类似于C中的main函数),并且必须拥有IO类型,通常为IO ()

但您没有必要使用do符号。实际上是do is syntactical sugar。您的main实际上是:

main =
    putStrLn "What's your name?" >> getLine >>= \n -> putStrLn ("Hello " ++ n)

或更优雅:

main = putStrLn "What's your name?" >> getLine >>= putStrLn . ("Hello " ++)

所以我们写了main没有do符号。有关 desugaring do表示法的更多信息,请参阅here

答案 1 :(得分:1)

是的,如果你的do块中有多行,而,如果你甚至使用do符号。< / p>

完整的do - 符号语法还包括显式分隔符 - 花括号和分号:

main = do { putStrLn "What's your name?" 
          ; name <- getLine  
          ; putStrLn ("Hello " ++ name) 
          }

使用它们,缩进在编码风格中不起作用(良好的缩进提高了可读性;显式分隔符确保代码稳健性,消除与空白相关的脆性)。所以当你只有一行IO代码时,比如

main = do { print "Hello!" }

没有分号,没有要注意的缩进,花括号和do关键字本身就变得多余了:

main = print "Hello!" 

所以,不,不是永远。但通常情况确实如此,代码的一致性对可读性有很大帮助。

do转换为IO - monadic代码,但您可以将此事实视为实现细节。事实上,你应该。您可以在心理上将do符号 axiomatically 视为嵌入式语言。此外,无论如何,就是这样。

简化的do - 语法是:

   do {  pattern1 <- action1
      ;  pattern2 <- action2
      .....................
      ;  return (.....)
      }

对于某些monad actioni和某些结果类型M ai,每个M都是ai类型的Haskell值,而每个操作都会生成自己的结果类型ai } 所有操作必须属于相同的 monad类型M

每个patterni接收先前的&#34;计算的&#34;相应行动的结果。

通配符_可用于忽略它。如果是这种情况,_ <-部分可以完全省略。

&#34;单子&#34;这是一个可怕而且没有信息的词,但从概念上讲它实际上只不过是EDSL。 嵌入式特定于域的语言意味着我们拥有本机Haskell值(在本例中为 I / O计算)。我们用这种语言编写 I / O 程序,这些程序成为本机Haskell值,我们可以像任何其他本机Haskell值一样操作 - 将它们收集在列表中,将它们组合成更复杂的计算描述(程序)等。

main值是由我们的Haskell程序计算的一个这样的值。编译器会看到它,并在运行时执行它所代表的 I / O 程序。

关键是我们现在可以拥有一个&#34;功能&#34; getCurrentTime(从表面而言,在功能范例中是不可能的,因为它必须在单独的调用上返回不同的结果),因为它返回当前时间 - 它描述的动作< em>将执行此操作,当 I / O 程序描述由运行时系统运行时。

在类型级别上,这个值反映的是这些值不仅仅是一些普通的Haskell类型a,而是一个参数化类型IO a,&#34;标记为&#34; IO属于 I / O 编程的这个特殊世界。