【问题标题】:Haskell simple If-then-else errorHaskell 简单的 If-then-else 错误
【发布时间】:2018-06-28 14:37:53
【问题描述】:

我对 Haskell 和编程很陌生。我正在尝试在不使用 Data.List 中的 sum 函数的情况下添加列表的内容。到目前为止,这是我所得到的:

module Summ
    where
summ :: [Int] -> Int
summ xs = 
  if null xs == False
    then let y = x + (head xs)
         let xs = tail xs
    else print y

我很确定这段代码有很多错误,但目前最新的错误是else 语句的“输入解析错误”。怎么了?

【问题讨论】:

  • y 在表达式的第一个分支中定义,但在后半部分使用。你期望发生什么?
  • 我在想我可以使用y 作为我用来添加列表元素的表达式的存储。我想不出另一种方法来做到这一点......
  • 看看Learn You a Haskell,它将引导您了解语法和解决问题的基础知识。
  • 我一直在用它和@haskellbook自学,还有其他好的资源吗?
  • 请记住,您现在使用的是一种纯函数式语言。没有“存储”或“变量”之类的东西(至少,不是通常意义上的)。这是一个巨大的调整,但为了在 Haskell 中高效编程,你必须习惯这种范式转变。

标签: haskell if-statement


【解决方案1】:

let 表达式的语法是let <i>BINDINGS</i> in <i>EXPRESSION</i>,例如

let x = 21 in x + x

它可能在抱怨else,因为它希望看到in

有一种let 没有in 的形式,但它只适用于do 块(或列表推导)。

【讨论】:

  • 之前出现的一个错误是我没有let。什么是仍然可以执行这些操作的替代方案?
  • @VeganJoy “那些操作”是什么意思?替代什么?
  • 我在这两种情况下都是指let之后的表达式,我真的不知道很多功能。我还可以在那里使用什么,或者in 在这里适用吗?
  • @VeganJoy 我不知道你想在那里做什么。您将y 定义为xxs 的第一个元素之和,但x 不存在。然后你将xs 定义为它自己的尾巴。我无法告诉您改用什么,因为我不明白您要做什么,也不知道其中的任何内容如何帮助您总结一个列表。
  • 嗯...我不知道我在想什么 x。我正在尝试获取列表的第一部分,将其添加到变量中,然后删除 xs 的第一个元素并重复直到它为空。一旦它为空,我计划让它打印已添加到的变量。
【解决方案2】:

这在我看来不太对劲。 print 返回 IO (),这不是 Intlet 部分似乎根本没有导致表达式,并且 x 没有定义。您是否尝试编写递归函数?

summ [] = 0
summ (x:xs) = x + summ xs

递归不是语法;这只是使用两个带有模式匹配的偏函数定义。其中一个再次调用summ,这是递归,最终(给定一个有限列表)该调用将导致更简单的非递归函数。该模式还将列表解构为头尾,所以函数等价于:

summ xs = if null xs
          then 0
          else head xs + summ (tail xs)

请注意,thenelse 分支都是相同类型的表达式。

每个定义都有summ :: Num t =&gt; [t] -&gt; t类型

【讨论】:

  • 我以前见过递归语法,但我不知道它是如何工作的。你能详细说明吗?编辑:也在第三行我定义类型应该是IO () 而不是Int?
  • @VeganJoy 你不应该在summ 函数中的任何地方使用IO。编译器可能会建议,因为你在那里有一个流浪的print 调用,但你不想在summ 函数中调用print;您只想简单地返回该值并让main 将其打印出来或做任何它想做的事情。
猜你喜欢
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2015-11-18
相关资源
最近更新 更多