为什么Haskell完全声明?

xet*_*a11 7 haskell declarative

我不太了解命令式声明性编程范式之间的区别.我读到Haskell是一种声明性语言.在某种程度上,我会说是的,但是在命令的定义方面有一些困扰我的东西.

当我有一个数据结构并使用Haskell的函数进行转换时,我实际上只是告诉了要转换的内容.所以我将datastruct作为函数的参数给出,并对结果感到满意.

但是,如果没有功能真正满足我的需求呢?

我会开始编写一个自己的函数,它希望datastruct作为参数.之后,我将开始编写如何处理数据结构.因为我只能调用本机Haskell函数,所以我仍然使用声明性范例吗?但是,当我开始使用"if语句"时.这不会结束声明性质,因为我要告诉程序如何从那一点做事情?

che*_*ner 8

ifHaskell中没有语句,只有一个if 表达式 if a then b else c,它实际上等同于类似a ? b : cC语言或b if a else cPython的三元表达式.您不能忽略else它,它可以在任何可以使用任意表达式的地方使用.进一步约束a必须具有类型Boolean,b并且c必须具有相同的类型.这是语法糖

case a of
  True -> b
  False -> c
Run Code Online (Sandbox Code Playgroud)

不要太挂在标签上"声明"; 它只是语言支持的一种编程风格.例如,考虑一个阶乘函数的典型声明性定义:

fact 0 = 1
fact n = n * fact (n - 1)
Run Code Online (Sandbox Code Playgroud)

对于你认为更迫切需要的东西,这也只是语法糖:

fact n = case n of 
          0 -> 1
          otherwise -> n * fact (n - 1)
Run Code Online (Sandbox Code Playgroud)

  • @chepner 这最后一个例子的匹配模式真的是必要的吗?因为它是一个表达式:| (2认同)

use*_*560 8

也许这是一个观点问题.我看待它的方式,没有必要用其他东西来定义事物,因为我们总是可以用它的定义替换某些东西(只要定义是纯粹的).也就是说,如果我们有f x = x + 1,那么我们看到的任何地方f z都可以替代z + 1.所以纯函数不应该被认为是指令; 它们应被视为定义.

由于这个原因,许多Haskell代码被认为是声明性的.我们简单地将事物定义为其他事物的(纯)函数.

也可以在Haskell中编写命令式代码.有时我们真的想说"做A,然后做B,然后做C".这为函数应用的简单世界增加了一个新的维度:我们需要一个"先发生过"的概念.Haskell已经接受了Monad概念来描述具有评估顺序的计算.这结果非常方便,因为它可以封装诸如改变状态之类的效果.

  • @ xetra11虽然"结尾"太强了一个词 - 毕竟`Monad`只是另一种类型,正如user2297560提醒我们的那样 - 我们可以说monads*可以用来以声明的方式表达命令性.然而,正如切普纳的回答所强调的那样,强制性在我们的头脑中比在实际的代码中更多. (3认同)

Dom*_*ese 5

坦率地说,"声明性编程"这个术语更像是一个营销术语而不是其他任何东西.非正式的定义,它意味着"指定做什么,而不是如何做"是模糊和开放的解释,绝对远离黑白边界.在实践中,它似乎适用于广泛分为功能编程,逻辑编程或域特定语言(DSL)类别的任何事物.

因此(我意识到这可能不符合你的问题的答案,但仍然:)),我建议你不要浪费你的时间想知道某些东西是否仍然是声明性的.命令性与功能性与逻辑性编程这两个术语已经有了更多的意义,因此对它们进行反思可能更有用.