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)
看起来您仍然以命令式方式(而不是功能方式)进行思考。例如:
y++)y在list函数体中使用“全局变量”(即)以下是您的问题的可能解决方案:
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。
你的程序看起来非常" 势在必行 ":你定义一个变量y,然后以某种方式写一个do,调用(?)list自动似乎"返回y"然后你想要增加的函数(?)y.
这不是Haskell(以及大多数功能和声明性)语言的工作方式:
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)