与列表模式比较

时间:2016-04-29 17:18:10

标签: haskell pattern-matching

首先考虑以下代码,它计算字符串中的空格数:

countSpaces :: String -> Int
countSpaces [] = 0
countSpaces (c : restOfString)
    = d + countSpaces restOfString
       where d = if c == ’ ’ then 1
                             else 0

以下是我的问题:

1,如果我拨打电话:countSpaces "abc",那么当此函数尝试将字符串"abc"(c: restOfString)匹配时会发生什么。我的意思是,restOfString在此次调用中为:"abc",但(c:restOfString)是什么?你正在“消耗”某些东西(变量?c)到restOfstring然后你想要匹配?我只是不明白。

2,我尝试运行代码但是我得到一个解析错误原因?

  

在输入'''

上解析错误

3,此函数会将countSpaces调用为无穷大吗?因为restOfString总是相同而不是减少,例如。拨打电话countSpaces "aaa"在第一次通话,第二次或任何通话后都不会改变,对吗?

  • 之后添加*

现在考虑完成相同任务的代码:

countSpaces :: String -> Int
countSpaces [] = 0
countSpaces (’ ’ : restOfString)
        = 1 + countSpaces restOfString
countSpaces (_ : restOfString)
        = 0 + countSpaces restOfString

1,所以如果我们尝试拨打电话countSpaces "abc",模式(’ ’ : restOfString)会变得更大,因为每次countSpaces被调用时,这只会导致' 'restOfString countSpaces,除非每次调用' ',否则字符串中的第一个字符将更改为:countSpaces "abc"。因此,在(’ ’ : restOfString)的第一次调用中,' ':"bc""a",这是令人困惑的,因为它将" abc"替换为空白而不是将其删除,以便我们得到:{ {1}}

1 个答案:

答案 0 :(得分:6)

  

1,如果我打电话:countSpaces“abc”,那么当这个函数试图将字符串“abc”与:(c:restOfString)匹配时会发生什么。

当您使用cons运算符:匹配该模式时,:左侧的元素是列表中的第一个元素,而:右侧的元素是余数的清单。以下是等效的:

"abc" == 'a' : "bc"

由于String是一个字符列表(具体来说,[Char]),因此上述内容也可以写成:

"abc" == 'a' : 'b' : 'c' : []
  

2,我尝试运行代码但是我得到一个解析错误原因?

您的解析错误是因为您对单引号使用了错误的字符。当您使用unicode 0x2019

时,您正在使用ASCII/Unicode Apostrophe character: '
  

3,这个函数会将countSpaces调用到无穷大吗?

如果你的字符串是无限的,它只会计入无穷大。减少实际上发生在这一部分:

 countSpaces restOfString

要了解原因,请参阅第1部分的答案。对于“abc”,restOfString为“bc”。

  

4,所以如果我们尝试调用countSpaces“abc”模式:('':restOfString)将变得更大,因为每次countSpaces被调用时,这只会对'restOfString有一个'',除非每次countSpaces都会得到调用然后字符串中的第一个字符将更改为:''。所以在第一次调用countSpaces“abc”然后('':restOfString)是'':“bc”,这是混淆吧?

我认为您的混淆源于模式匹配和构建列表看起来相同的事实。即,当你写(' ':restOfString)时会发生什么,完全取决于背景。

您可以将函数定义视为分为由=符号分隔的两个部分:

countSpaces (' ' : restOfString)   =   1 + countSpaces restOfString
^                              ^   ^   ^                          ^
|                              |   |   |                          |
--------------------------------   |   ----------------------------
               |                   |                 |
        Pattern Matching       Separator       Function Body

模式匹配部分不会影响输出。当您在模式匹配方面使用(' ' : restOfString)时,您会说,“如果传递给countSpaces函数的参数以空格开头,则返回此函数体中的内容。如果第一个字符是不是空格,然后尝试定义的下一个模式“。在任何一种情况下(无论是否匹配),传递给countSpaces的值都不会以任何方式被修改(它没有放在它前面的空格;这种事情只发生在函数体中)。

相反,当你将(' ' : restOfString)放在函数体中时,你会说“返回带有空格字符前缀的restOfString”。