2012-02-05 81 views
29

我已经浏览过的许多Haskell教程几乎完全集中在几乎完全没有涵盖如何构造程序的语法上。Haskell程序的基本结构

例如...

这里有一个C的一个最基本的轮廓++应用程序:

#include <iostream> 
using namespace std; 

int addition (int a, int b) 
{ 
    int r; 
    r=a+b; 
    return (r); 
} 

int main() 
{ 
    int z; 
    z = addition (5,3); 
    cout << "The result is " << z; 
    return 0; 
} 

当我第一次开始学习C++,像这样的例子让我非常学习如何组装个人件进工作方案。也许我正在寻找错误的地方,但是我一直无法找到任何对Haskell来说都很直接和简单的例子。

我已经知道很多Haskell语法。我可以编写递归列表解析,并操纵字符串,整数和列出wazoo。

总之:我只想知道两个子例程和变量传递在Haskell中看起来是什么样子。如果我能够对如何构建Haskell程序有一些基本的了解,那么我最终可以将我学到的所有语法都用到某种用途上。

+2

我会从像http://www.haskell.org/haskellwiki/Haskell_in_5_steps这样的地方开始学习Clojure。不过,我确实有O'Reilly Haskell的书,而这本书 - http://www.nostarch.com/lyah.htm - 似乎正在得到很多好评。 – octopusgrabbus 2012-02-05 22:20:37

+3

虽然这是一个合理的问题,但请允许我建议您接近Haskell有一点错误。 Haskell尽可能强调纯函数,大多数Haskell实现提供了一个REPL(读 - 评估 - 打印循环),您可以在其中定义函数。我强烈建议,不要制作打印到stdout的小程序,只需编写函数并在ghci中使用它们播放。我想你会发现学习Haskell更加灵活和有趣。 – 2012-02-05 23:21:36

+0

@DanBurton我可能花了上个月阅读语法,并在ghci中使用函数和列表解析。我准备好现在制作一个节目。 (:D你说得对,因为我一直在接近Haskell的错误,我试图将过程式编程原则应用于函数式编程语言,我仍然试图围绕如何将一堆函数转化为某些东西它可以做的不只是运行一次并停止,我会继续阅读 – 2012-02-06 00:31:22

回答

32

Haskell程序的结构非常简单。你有一个main功能,这是IO,这就是它。所以基础:

module Main where 

addition a b = a + b 

main :: IO() 
main = do let z = addition 5 3 
      putStrLn $ "The result is: " ++ show z 

现在你可以使用像这样编译成一个简单的程序:

ghc --make Main.hs -o program 

,它应该产生调用的程序的可执行文件。

一般来说,程序的结构主要是纯粹的函数,实际的计算结合了处理IO的代码的分立部分。 (当然也有例外,但编写尽可能多的纯代码的一般想法是相当普遍的。)

由于几乎所有东西都表示为一组纯函数,因此不会在它们之间传递变量 - - 函数通过传递参数进行通信。

代码IO的部分代码位于main。在大多数情况下,全部你的IO将通过main;即使您单独编写IO操作并给出它们的名称,它们最终也会从main开始执行。

Haskell中的“函数组”被称为“模块”。您可以有多个模块,每个模块都有自己的文件:

module Blarg (exportedFunction) where 

helper a b = ... -- this will *not* be exported 
exportedFunction a b = helper a b -- this *will* be exported 

只有括号中的标识符才会真正导出;其余的都是隐藏的。如果您根本不包括括号,则默认情况下会导出所有内容。

将本文件保存为Blarg.hs。现在,您可以在Main导入:

import Blarg 

到组函数的另一个有效方法是where

complicatedFunction a b c = helper 0 
    where helper count = ... 

这样helper仅在范围为complicatedFunction,也有获得abccomplicatedFunction

+0

谢谢您的回复。我熟悉main,但是如何制作其他子例程,并让这些子例程相互通信并传递变量? – 2012-02-05 22:22:06

+3

你并没有真正的“子程序”,你有*功能*。由于没有突变,你可以将值作为参数传递给这些函数(例如,在我的示例中为'addition 5 3')。 – 2012-02-05 22:23:54

+0

没错。我的意思是说,你如何制作其他“功能组”?基本上,我试图不把所有东西都放在主要位置。 – 2012-02-05 22:26:11