List 如何将尾端与正确的类型匹配?

List 如何将尾端与正确的类型匹配?,list,scala,List,Scala,我使用case-first::rest模式递归地分解列表。但显然,这使得rest成为一个List[Any],即使原始列表是特定类型的 我尝试将其更改为case first::(rest:List[Char]),但这只会产生一个更混乱、不相关的错误。如果可以避免的话,我宁愿不投 下面是完整的代码(我使用的是SimplyScala.com)。是的,我试着变得狡猾,作为探索语言的一种方式 def paren(chars: List[Char], ct:Int = 0): Boolean = {

我使用
case-first::rest
模式递归地分解列表。但显然,这使得
rest
成为一个
List[Any]
,即使原始列表是特定类型的

我尝试将其更改为
case first::(rest:List[Char])
,但这只会产生一个更混乱、不相关的错误。如果可以避免的话,我宁愿不投


下面是完整的代码(我使用的是SimplyScala.com)。是的,我试着变得狡猾,作为探索语言的一种方式

def paren(chars: List[Char], ct:Int = 0): Boolean = {
    case Nil => ct==0
    case c::tl => {
        paren(tl, ct + (c match { //!ERROR! tl is a List[Any] instead of List[Char]
            case '(' => 1
            case ')' => -1
            case _ => 0
        }))
    }
}

您更适合在匹配项上使用防护,而不是嵌套匹配项:

def paren(chars: List[Char], ct: Int = 0): Boolean = chars match {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(t, ct + 1)
  case h :: t if h == ')' => paren(t, ct - 1)
  case h :: t => paren(t, ct)
}
通过添加
字符匹配{…}
,语句的编译就可以了

如果不想使用
chars match{…}
部分,则需要将其用作
PartialFunction
,这将涉及切换参数的顺序,即:

def paren(ct: Int = 0): List[Char] => Boolean = {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(ct + 1)(t)
  case h :: t if h == ')' => paren(ct - 1)(t)
  case h :: t => paren(ct)(t)
}
如果您不介意使用,那么您可以使用它们已经提供的
Foldable
IntMonoid
类型类,使事情变得更加简单。您只需要提供一个简单的函子来转换
Char=>Int
,如下所示:

import scalaz._, Scalaz._

val paren: List[Char] => Boolean = _.foldMap({(_: Char) match {
  case '(' => 1
  case ')' => -1
  case _ => 0
}}) === 0

您更适合在匹配项上使用防护,而不是嵌套匹配项:

def paren(chars: List[Char], ct: Int = 0): Boolean = chars match {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(t, ct + 1)
  case h :: t if h == ')' => paren(t, ct - 1)
  case h :: t => paren(t, ct)
}
通过添加
字符匹配{…}
,语句的编译就可以了

如果不想使用
chars match{…}
部分,则需要将其用作
PartialFunction
,这将涉及切换参数的顺序,即:

def paren(ct: Int = 0): List[Char] => Boolean = {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(ct + 1)(t)
  case h :: t if h == ')' => paren(ct - 1)(t)
  case h :: t => paren(ct)(t)
}
如果您不介意使用,那么您可以使用它们已经提供的
Foldable
IntMonoid
类型类,使事情变得更加简单。您只需要提供一个简单的函子来转换
Char=>Int
,如下所示:

import scalaz._, Scalaz._

val paren: List[Char] => Boolean = _.foldMap({(_: Char) match {
  case '(' => 1
  case ')' => -1
  case _ => 0
}}) === 0

您更适合在匹配项上使用防护,而不是嵌套匹配项:

def paren(chars: List[Char], ct: Int = 0): Boolean = chars match {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(t, ct + 1)
  case h :: t if h == ')' => paren(t, ct - 1)
  case h :: t => paren(t, ct)
}
通过添加
字符匹配{…}
,语句的编译就可以了

如果不想使用
chars match{…}
部分,则需要将其用作
PartialFunction
,这将涉及切换参数的顺序,即:

def paren(ct: Int = 0): List[Char] => Boolean = {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(ct + 1)(t)
  case h :: t if h == ')' => paren(ct - 1)(t)
  case h :: t => paren(ct)(t)
}
如果您不介意使用,那么您可以使用它们已经提供的
Foldable
IntMonoid
类型类,使事情变得更加简单。您只需要提供一个简单的函子来转换
Char=>Int
,如下所示:

import scalaz._, Scalaz._

val paren: List[Char] => Boolean = _.foldMap({(_: Char) match {
  case '(' => 1
  case ')' => -1
  case _ => 0
}}) === 0

您更适合在匹配项上使用防护,而不是嵌套匹配项:

def paren(chars: List[Char], ct: Int = 0): Boolean = chars match {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(t, ct + 1)
  case h :: t if h == ')' => paren(t, ct - 1)
  case h :: t => paren(t, ct)
}
通过添加
字符匹配{…}
,语句的编译就可以了

如果不想使用
chars match{…}
部分,则需要将其用作
PartialFunction
,这将涉及切换参数的顺序,即:

def paren(ct: Int = 0): List[Char] => Boolean = {
  case Nil => ct == 0
  case h :: t if h == '(' => paren(ct + 1)(t)
  case h :: t if h == ')' => paren(ct - 1)(t)
  case h :: t => paren(ct)(t)
}
如果您不介意使用,那么您可以使用它们已经提供的
Foldable
IntMonoid
类型类,使事情变得更加简单。您只需要提供一个简单的函子来转换
Char=>Int
,如下所示:

import scalaz._, Scalaz._

val paren: List[Char] => Boolean = _.foldMap({(_: Char) match {
  case '(' => 1
  case ')' => -1
  case _ => 0
}}) === 0


这正是我之前所知道的,mod var name。您使用的是哪个版本的Scala导致了错误?SimplyScala.com。是否有可能我只是不被允许做
:type={…}
,并且必须使用
:type=chars匹配{…}
?那会很尴尬的,是的。我对你的答案投了赞成票,因为我注意到了其中的语法错误。现在不确定该怎么处理这个问题。“更适合在匹配项上使用防护,而不是嵌套匹配项[…],那么类型推断器就可以正常工作了。”-不过,并不是防护使其正常工作。只需添加
chars match
就足以使类型推断生效,这正是我之前所做的,mod var names。您使用的是哪个版本的Scala导致了错误?SimplyScala.com。是否有可能我只是不被允许做
:type={…}
,并且必须使用
:type=chars匹配{…}
?那会很尴尬的,是的。我对你的答案投了赞成票,因为我注意到了其中的语法错误。现在不确定该怎么处理这个问题。“更适合在匹配项上使用防护,而不是嵌套匹配项[…],那么类型推断器就可以正常工作了。”-不过,并不是防护使其正常工作。只需添加
chars match
就足以使类型推断生效,这正是我之前所做的,mod var names。您使用的是哪个版本的Scala导致了错误?SimplyScala.com。是否有可能我只是不被允许做
:type={…}
,并且必须使用
:type=chars匹配{…}
?那会很尴尬的,是的。我对你的答案投了赞成票,因为我注意到了其中的语法错误。现在不确定该怎么处理这个问题。“更适合在匹配项上使用防护,而不是嵌套匹配项[…],那么类型推断器就可以正常工作了。”-不过,并不是防护使其正常工作。只需添加
chars match
就足以使类型推断生效,这正是我之前所做的,mod var names。您使用的是哪个版本的Scala导致了错误?SimplyScala.com。是否有可能我只是不被允许做
:type={…}
,并且必须使用
:type=chars匹配{…}
?那会很尴尬的,是的。我对你的答案投了赞成票,因为我注意到了其中的语法错误。现在不确定该怎么处理这个问题。“更适合在匹配项上使用防护,而不是嵌套匹配项[…],那么类型推断器就可以正常工作了。”-不过,并不是防护使其正常工作。只需添加
chars match
就足以使类型推断生效。您能解释一下为什么不想使用
def paren(chars:List[Char],ct:Int=0):Boolean=chars match{
?With