Haskell中没有"length"函数的列表的长度

Cor*_*eze 1 haskell functional-programming imperative-programming string-length

我想查看列表有多长,但不使用该函数length.我写了这个程序,它不起作用.也许你可以告诉我为什么?谢谢!

let y = 0
main = do
  list (x:xs) = list (xs)
  y++

list :: [Integer] -> Integer
list [] = y
Run Code Online (Sandbox Code Playgroud)

Rob*_*son 5

看起来您仍然以命令式方式(而不是功能方式)进行思考。例如:

  • 您尝试更改“变量”的值(即y++
  • 您尝试ylist函数体中使用“全局变量”(即)

以下是您的问题的可能解决方案:

main = print $ my_length [1..10]

my_length :: [Integer] -> Integer
my_length [] = 0
my_length (_:xs) = 1 + my_length xs
Run Code Online (Sandbox Code Playgroud)

您也可以在此处运行此代码:http : //ideone.com/mjUwL9

另请注意,没有必要要求您的列表包含Integer值。实际上,您可以通过使用以下声明来创建函数的更多“不可知”版本:

my_length :: [a] -> Integer
Run Code Online (Sandbox Code Playgroud)

此函数的实现不依赖于列表中项目的类型,因此您可以将它用于任何类型的列表。相比之下,对于例如my_sum函数(一种计算给定列表中元素总和的潜在函数),您就不能那么自由了。在这种情况下,您应该定义您的列表由一些数字类型的项目组成。

最后,我想向您推荐一本关于 Haskell 编程的精彩书籍:http : //learnyouahaskell.com/chapters


Wil*_*sem 5

你的程序看起来非常" 势在必行 ":你定义一个变量y,然后以某种方式写一个do,调用(?)list自动似乎"返回y"然后你想要增加的函数(?)y.

这不是Haskell(以及大多数功能和声明性)语言的工作方式:

  • 在声明性语言中,只定义一个变量一次,在设置值后,通常无法改变其值,
  • 在Haskell中,a do通常用于monad,而它length函数,
  • let是一个语法结构,用于定义表达式范围内的变量,
  • ...

为了编写Haskell(或任何函数式语言),您需要"思考功能":思考如何使用函数数学方式解决问题.

在数学中,你会说空列表[]显然有长度0.此外,在列表不为空的情况下,存在第一元素("头部")和剩余元素("尾部").在这种情况下,结果是一加尾的长度.我们可以用数学表达式转换它,例如:

胶乳

现在我们可以轻松地将该函数转换为以下Haskell代码:

ownLength :: [a] -> Int
ownLength [] = 0
ownLength (_:xs) = 1 + ownLength xs
Run Code Online (Sandbox Code Playgroud)

现在在Haskell中,通常还使用累加器来执行尾递归:通过递归调用和每次更新变量时传递参数.当你到达递归的末尾时,你会返回 - 有时是在一些后处理之后 - 累加器.

在这种情况下,累加器将是迄今为止看到的长度,因此您可以写:

ownLength :: [a] -> Int
ownLength = ownLength' 0
    where ownLength' a [] = a
          ownLength' a (_:xs) = ownLength' (a+1) xs
Run Code Online (Sandbox Code Playgroud)