4

私はScalaにまったく慣れていません。現在、Standard MLで作成したパーサーをScalaに移植しようとしていますが、次のコードで問題が発生しています。

abstract class Token
case class Zero extends Token
case class At extends Token
//...

object Tokenizer {
  def tokenize(seq : List[Char]) : List[Token] = seq match {
    case List() => error("Empty input")
    case '0' :: rest => Zero :: tokenize(rest)
    case '@' :: rest => At :: tokenize(rest)
    //...
  }  
}

SMLではtokenize()メソッドの戻り型を宣言する必要はありませんが、Scalaはそれを必要としているようで、私が提供した型にはどういうわけか満足していません(Zero、Atは無効な型であり、代わりにトークンタイプの)。また、解析フェーズの後の時点で、トークンリストとパターンを一致させたいことに注意してください。

私はウェブとstackoverflow自体を検索して、以前に同様の質問が提起されたかどうかを確認しましたが(非常に些細なことのように見えました)、どういうわけか何も見つかりませんでした。私は何か基本的な間違いを犯していると確信しています。遠慮なく私に教えてください:)

4

2 に答える 2

9

AtおよびZeroはクラスであり、オブジェクトではないため、それ自体はのインスタンスではありませんTokencase classからに変更することでコードを修正できますcase object

case object Zero extends Token
case object At extends Token

関数の戻り型を指定する必要がある理由は、Scalaのコンパイラーが再帰関数の型を理解できないためです。詳細については、こちらを参照してください。Scalaが再帰関数の戻り型を必要とするのはなぜですか。

于 2011-08-15T19:49:51.880 に答える
8

ZeroAtcaseクラスの新しいインスタンスを作成する場合は、applyファクトリメソッドを使用してそれらをインスタンス化する必要があります(またはnewキーワードnew Zero:) 。Zero()Zero.apply()

case '0' :: rest => Zero() :: tokenize(rest)

単にZero(ではなく)書く場合は、コンパイラによって自動的に作成されたクラスZero()のコンパニオンオブジェクトを使用しています。Zero

于 2011-08-15T19:53:02.847 に答える