1

Map入力を受け取りCaseクラスを出力できるパーサーを構築したいと思います。現在、FPを利用していないように見える命令型コードがいくつかあります。Caseクラスを出力できるパーサーを構築する方法がわかりません。

これが私が持っているものです:

def fromMap(m: Map[String,AttributeValue]): User =  {
    val id = m.get("user-id") map {_.getS}
    val email = m.get("email").get.getS
    val name = m.get("name").get.getS
    val openId = m.get("openId") map {_.getS}
    User(id, email, name, openId)
}

更新: 私はAnormに似た何かをしたいが、スカラのパーサーコンビネーターを使って何かをしたいということをもっと明確にすべきだったと思います。上記の問題は、柔軟性や再利用性がないことです。発信者は、取得したものだけを取得する必要があります。

パーサーコンビネーターがマップ形式の結果を解析するための正しいアプローチになることを願っています。ご想像のとおり、私はDyanmoDBを使用しています。

更新2: どうやら私は問題をうまく説明することができません。私がやりたいのは、呼び出し元が指定したバインディングを使用して、呼び出し元が選択したCaseクラスにマップを変換できる1つ以上のPareserCombinatorを作成することです。入力マップ=>出力ケースクラス

更新3: https ://github.com/wfaler/scala-dynamoは面白そうに見えますが、パーサーコンビネーターを使用していません。

4

2 に答える 2

3

@4e6 と同様の回答ですが、Scala の組み込みメソッドでのみ実現されます。

case class User(id: String, email: String, name: String, openId: String)

val m = Map("user-id" -> "123", "email" -> "test@test.org", "name" -> "testuser", "openId" -> "456")

def fromMap(m: Map[String, String]): Option[User] = for {
  id <- m get "user-id"
  email <- m get "email"
  name <- m get "name"
  openId <- m get "openId"
} yield User(id, email, name, openId)

scala> fromMap(m)
res0: Option[User] = Some(User(123,test@test.org,testuser,456))
于 2012-04-25T08:18:23.010 に答える
1

scalaz ApplicativeBuilderはあなたが探しているものだと思います。Optionまた、例外を回避する方法として、an を返すことをお勧めします。何がわからないgetSので、スニペットの簡略版は次のようになります。

case class User(val id: String, val email: String, val name: String, val OpenId: String)

def fromMap(m: Map[String, String]): Option[User] = {
  val id = m.get("user-id")
  val email = m.get("email")
  val name = m.get("name")
  val openId = m.get("openId")
  id |@| email |@| name |@| openId apply User
}

混乱を避けるために、 のapplyメソッドはApplicationBuilder実際には関数を使用するため、冗長バージョンは次のとおりです。

(id |@| email |@| name |@| openId) { (id, email, name, openId) =>
  new User(id, email, name, openId)
}

アプリケーションのその他の例は、ここで見つけることができます

于 2012-04-25T07:33:36.333 に答える