簡體   English   中英

Scala簡化了嵌套monad

[英]Scala simplify nested monads

我有一些用Lift編寫的代碼。 基本上它的嵌套Box(類似monad to Option)。 如果可能的話,我想稍微簡化一下。 最好添加類型參數,這樣可以根據需要輕松更改為字符串或雙精度。 這是代碼

tryo(r.param("boolean parameter").map(_.toBoolean)).map(_.openOr(false)).openOr(false)

“tryo”是輔助函數,用於捕獲並在Box中包含結果,如果發生異常且r是Req對象。 “param”函數返回Box [String](來自請求參數)。 我想讓它適用於Int的String等等,如果可能的話,擺脫嵌套的map / openOr(你認為在Option類型中有getOrElse)。

Monad變形金剛?

那個sh * t的flatMap

r.param("boolean parameter").flatMap(tryo(_.toBoolean)).openOr(false)

或者,使用一個理解:

val result = for {
  param <- r.param("boolean parameter")
  bool <- tryo(param.toBoolean)
} yield bool
result openOr false

但這並不能解決你獲得不同類型的能力。 為此我會建議像:

def asOrDefault[T](input: Box[Any])(default: => T): T = input.flatMap(tryo(_.asInstanceOf[T])).openOr(default)

asOrDefault(r.param("any param"))(0)

這是未經測試的...另請注意, scala.util.control.Exception.allCatch.opt()將返回一個Option ,就像tryo返回一個Box

如果要抽象類型,則需要抽象默認值和字符串轉換:

case class Converter[T]( default: T, fromString: String => T )

然后為您的類型定義隱式實例:

implicit val intConverter = Converter[Int]( 0, _.toInt )
implicit val boolConverter = Converter[Boolean]( false, _.toBoolean )

最后,使用pr1001回答,使用隱式提供的轉換器值:

def asOrDefault[T](input: Box[String])(implicit conv: Converter[T]): T = input.flatMap(
  s => tryo( conv.fromString(s))).openOr(conv.default)

編譯器將為您選擇適當的轉換器實例:

asOrDefault[Int]( input.param("some int param") )
asOrDefault[Boolean]( input.param("some boolean param") )

我在@ pr1001和@paradigmatic的基礎上進行了一些調整版本。

case class Converter[T]( fromString: String => T )

implicit val boolConverter = Converter(_.toBoolean) 

implicit val intConverter = Converter(_.toInt)

def asOrDefault[T](input: Box[String], default: T)(implicit conv: Converter[T]): T =       
  input.flatMap( s => tryo(conv.fromString(s))).openOr(default)

在我的情況下使用:

def prettyPrint(implicit r: Req) = asOrDefault(r.param("prettyPrint"), false)

def maxResults(implicit r: Req): Int = asOrDefault(r.param("maxResults"), 20)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM