我正在玩这种语言开始学习,而且我对于递归定义的工作原理感到困惑。
例如,让我们采用三角数的序列(TN n = sum [1..n]
)
提供的解决方案是:
triangularNumbers = scanl1 (+) [1..]
到目前为止,非常好。
但我提出的解决方案是:
triangularNumbers = zipWith (+) [1..] $ 0 : triangularNumbers
这也是正确的。
现在我的问题是:这如何转化为较低级别的实施?当满足这样的递归定义时,场景背后会发生什么?
答案 0 :(得分:5)
这是一个简单的递归函数,它为您提供第n个三角形数字:
tweets=[]
user_input=input('Tweets to be labeled:')
readdata=csv.reader(open(user_input,'r'))
for row in readdata:
tweets.append(row)
Header = tweets[0]
tweets.pop(0)
Academic_test_tweets=tweets[:]
Tweets=[]
for (words) in tweets:
bigram=[]
bigram_list=[]
words_filtered = [e.lower() for e in WordPunctTokenizer().tokenize(words) if len(e) >= 3]
words_filtered=[re.sub(r'(.)\1+', r'\1\1', e) for e in words_filtered if len(e)>=3]
bigram_words=bigrams(words_filtered)
for x in bigram_words:
bigram.append(x)
for (bi) in bigram:
bigram_word=bi[0]+bi[1]
bigram_list.append(bigram_word)
list_to_append=words_filtered+bigram_list
Tweets.append(list_to_append)
Academic_test_tweets_words=Tweets[:]
您的解决方案triag 0 = 0
triag n = n + triag (n-1)
更有趣:它是 corecursive (click,click)。在给定初始段的情况下,通过递归地指定下一个值来定义整个无限三角数序列,而不是通过将第n个数减少到较小输入的值来计算第n个数。
Haskell如何处理这样的核心运行?当它遇到您的定义时,实际上没有执行任何计算,它将被推迟到需要进一步计算的结果。当您访问列表triag' = zipWith (+) [1..] $ 0 : triag'
的特定元素时,Haskell会根据定义开始计算列表的元素,直到访问的元素为止。有关详细信息,我发现有关惰性评估的this文章很有帮助。总之,除非您需要预测内存使用情况,否则延迟评估很有用。
Here是一个类似的SO问题,逐步解释了triag'
的评估,这是Fibonacci序列的一个核心定义。