【问题标题】:Basic Structure of a Haskell ProgramHaskell 程序的基本结构
【发布时间】:2012-02-05 22:15:49
【问题描述】:

我看过的许多 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 程序有一些基本的了解,我可能最终能够将我学到的所有语法都用于某些用途。

【问题讨论】:

  • 我会从 haskell.org/haskellwiki/Haskell_in_5_steps 这样的地方开始,我正在学习 Clojure。不过,我确实有 O'Reilly Haskell 的书,而且这本书 -- nostarch.com/lyah.htm -- 似乎得到了很多好评。
  • 虽然这是一个合理的问题,但请允许我建议您接近 Haskell 略有错误。 Haskell 尽可能强调纯函数,并且大多数 Haskell 实现提供了一个 REPL(读取-评估-打印循环),您可以在其中使用您定义的函数。我强烈建议不要编写打印到标准输出的小程序,而只需编写函数并在 ghci 中使用它们。我想你会发现学习 Haskell 更加灵活有趣。
  • @DanBurton 上个月我可能一直在阅读语法,并在 ghci 中使用函数和列表推导。我现在准备做一个程序。 (:D你是对的,我一直在错误地接近Haskell。我正在尝试将过程编程原则应用于函数式编程语言。我仍在努力思考如何将一堆函数变成某种东西它可以做的不仅仅是运行一次就停止。我会继续阅读。
  • @octopusgrabbus 这是我第一次看到 Haskell in 5 Steps 链接。据我所知,我可以通过主调用和循环下面列出的各种函数来制作一个 Haskell 程序?
  • @SubtleArray: 没有“下层”:在 Haskell 中,函数可以在源文件中以任意顺序排列。

标签: function haskell data-structures subroutine


【解决方案1】:

Haskell 程序的结构非常简单。您有一个执行 IO 的 main 函数,仅此而已。所以基础知识:

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 的范围内,并且还可以从complicatedFunction 访问abc

【讨论】:

  • 感谢您的回复。我对 main 很熟悉,但是如何制作其他子程序,并让这些子程序相互通信和传递变量?
  • 你没有真正的“子程序”,你有函数。由于没有突变,因此您将值作为参数传递给这些函数(例如我的示例中的 addition 5 3)。
  • 对。我的意思是,你如何制作其他“功能组”?基本上,我尽量不把所有东西都放在 main 中。
  • 有关 Haskell 模块的信息请参见此 wiki 页面:haskell.org/tutorial/modules.html
  • @dflemstr:那不是 wiki 页面,那是温和的介绍 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多