2012-04-25 101 views
1

我想構建一個解析器,它可以接收地圖輸入並輸出一個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) 
} 

UPDATE: 我想我應該更清楚,我想這樣做斯卡拉類似ANORM但隨着解析器組合的東西。上述問題是不靈活或可重用的。來電者必須拿取他們所得到的。

我希望解析器組合器將是在地圖表單中解析結果的正確方法。正如你可能猜到的,我正在與DyanmoDB合作。

UPDATE 2: 顯然我不能很好地解釋這個問題。我想要做的就是編寫一個或多個Pareser Combinator,它可以使用調用者指定的綁定將Map轉換爲調用者選擇的Case類。輸入地圖=>輸出案例類

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

+0

這是用於DynamoDB的嗎? – Nick 2012-04-25 15:03:12

+0

是。我試圖將發電機結果綁定到案例類。 – dres 2012-04-25 18:23:47

+0

我不明白你的更新。什麼是你的輸入值,你最終想要得到什麼? – sschaef 2012-04-25 18:29:29

回答

1

我認爲scalazApplicativeBuilder是你在找什麼。此外,返回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 
} 

爲了避免混淆,的ApplicationBuilderapply方法其實需要一個功能,所以詳細的版本是

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

應用程序的更多示例可以發現here

+0

我需要避免scalaz,但看到我的更新以上關於解析器組合。這只是一個讓它工作的功能。我不認爲這是一個好設計。 – dres 2012-04-25 18:25:09

3

與@ 4e6類似的問題,但只有使用Scala內置方法才能實現:

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

val m = Map("user-id" -> "123", "email" -> "[email protected]", "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,[email protected],testuser,456)) 
+0

一旦嘗試過,我對斯卡拉留下了深刻的印象,並且隨着時間的推移,它開始思考有時會忘記核心Scala函數:) – 4e6 2012-04-25 09:25:52

+0

這會返回一個'Option'。這很好,你應該提到它。 – ziggystar 2012-04-25 11:55:05

+0

我需要避免scalaz,但看到我的更新以上有關Parser Combinators。這只是一個讓它工作的功能。我不認爲這是一個好設計。 – dres 2012-04-25 18:24:50