1

我想构建一个可以接受 Map 输入并输出 Case 类的 Parser。现在我有一些似乎没有利用 FP 的命令式代码。我只是看不到如何构建一个可以输出 Case 类的 Parser。

这是我所拥有的:

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 但使用 scala 中的 Parser Combinators 的事情。上述问题是不灵活或不可重用的。调用者必须拿走他们得到的东西。

我希望解析器组合器将是解析 Map 形式结果的正确方法。正如您可能已经猜到的那样,我正在使用 DyanmoDB。

更新2: 显然我不能很好地解释这个问题。我要做的就是编写一个或多个 Pareser 组合器,它们可以使用调用者指定的绑定将 Map 转换为调用者选择的 Case 类。输入映射 => 输出案例类

更新 3: https ://github.com/wfaler/scala-dynamo看起来很有趣,但不使用解析器组合器。

4

2 回答 2

3

与@4e6 类似的答案,但仅使用 Scalas 内置方法实现:

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作为避免异常的一种方式,最好返回一个。不知道是什么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 回答