ATuin

Replace placeholders using Applicatives (Scala)

Aug 26th, 2013
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.02 KB | None | 0 0
  1.     // Usign Applicatives to replace ':value' placeholders in a string
  2.     // All errors are accumulated into a ValidationNEL
  3. sealed trait ParamsReplacer {
  4.   val str: String
  5.   private val r = ":([a-zA-Z0-9]+)".r
  6.   private def f(p:Params) = (m:Match) => {
  7.     val s = m.toString.drop(1)
  8.     (p get s).toSuccess(s"Param '$s' is required").toValidationNEL
  9.   }
  10.  
  11.   def replace(params: Params) = {
  12.     val reduce = (a: String, b: (Match, String)) => b._1.matched.r.replaceFirstIn(a, b._2)
  13.     val zipAndReduce = (a:List[Match], b:List[String]) => (a zip b).foldLeft(str)(reduce)
  14.     val matchList = r.findAllMatchIn(str).toList
  15.  
  16.     (matchList.successNel[String] |@|
  17.       (matchList <*> f(params).pure[List]).sequenceU)(zipAndReduce)
  18.   }
  19. }
  20.  
  21. object ParamsReplacer {
  22.   def apply(s: String):ParamsReplacer = new ParamsReplacer {
  23.     val str = s
  24.   }
  25. }
  26.  
  27. // Use:
  28. scala> val rep = ParamsReplacer("retweets_of_me.:format.:test")
  29. rep: com.logikujo.Spore.ParamsReplacer = com.logikujo.Spore.ParamsReplacer$$anon$1@7ce9a760
  30.  
  31. // Scary type :) The cool part is the Failure(NonEmptyList(Error1, Error2))
  32. scala> rep.replace(Map.empty)
  33. res1: scalaz.Unapply[scalaz.Apply,scalaz.ValidationNEL[String,List[scala.util.matching.Regex.Match]]]{type M[X] = scalaz.ValidationNEL[String,X]; type A = List[scala.util.matching.Regex.Match]}#M[String] = Failure(NonEmptyList(Param 'format' is required, Param 'test' is required)
  34.  
  35. scala> rep.replace(Map("format" -> "json"))
  36. res3: scalaz.Unapply[scalaz.Apply,scalaz.ValidationNEL[String,List[scala.util.matching.Regex.Match]]]{type M[X] = scalaz.ValidationNEL[String,X]; type A = List[scala.util.matching.Regex.Match]}#M[String] = Failure(NonEmptyList(Param 'test' is required))
  37.  
  38. // A Success! :)
  39. scala> rep.replace(Map("format" -> "json", "test" -> "JustATest"))
  40. res4: scalaz.Unapply[scalaz.Apply,scalaz.ValidationNEL[String,List[scala.util.matching.Regex.Match]]]{type M[X] = scalaz.ValidationNEL[String,X]; type A = List[scala.util.matching.Regex.Match]}#M[String] = Success(retweets_of_me.json.JustATest)
Advertisement
Add Comment
Please, Sign In to add comment