Avoiding calling "point" every time I need empty Writer - scalaz

type EventWriter[A] = Writer[List[Event], A]
type EitherWriter[A] = EitherT[EventWriter, String, A]
def applyChange(event: Event): EitherWriter[Aggregate] =
EitherT.right[EventWriter, String, Aggregate](handleEvent(event).set(event :: Nil))
and this is used like:
def close = {
if (!closed) {
applyChange(Closed(id))
} else {
this.point[EitherWriter]
}
}
Can I avoid explicitly returning this.point[EitherWriter] every time I want to return this with empty list?

Related

How to convert scala.some to scala.mutable.Map?

i am trying to write code to mask nested json fields..
def maskRecursively(map :mutable.Map[String,Object]):mutable.Map[String,Object] ={
val maskColumns = PII_Data.getPIIData()
for((k,v) <- map){
if(v.isInstanceOf[Map[String,Object]]){
maskRecursively(map.get(k).asInstanceOf[mutable.Map[String,Object]])
}else if(v.isInstanceOf[List[Object]]) {
} else {
if(maskColumns.contains(k)){map+=(k->"*****")}
}
}
map }
calling this method from ..
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val result = mapper.readValue(jsonStr, classOf[ java.util.Map[String,Object] ])
import scala.collection.JavaConverters._
val myScalaMap = result.asScala
maskRecursively(result.asScala)
i am getting error while trying to iterate a nested json object ..
Cannot cast value of type 'scala.Some' to type 'scala.collection.mutable.Map'
how do i recurse a complex nested json object this way ?
Your mistake was
if(v.isInstanceOf[Map[String,Object]]){
maskRecursively(map.get(k).asInstanceOf[mutable.Map[String,Object]])
There are a few issues:
You check if v is an instance of Map, but then attempt to cast it to mutable.Map. They are technically different types (mutable vs immutable).
You check the type of v, but then apply the cast to map.get(k), which is going to be a different value and type from v. A map's get method returns an Option, hence the error message.
Thanks to type erasure on the JVM, the runtime won't be able to tell the difference between e.g. a Map[String, Object] and a Map[SomethingElse, Whatever] - both will just look like Map at runtime. The compiler should have given you a warning about the isInstanceOf call for this reason.
If you do an isInstanceOf / asInstanceOf combo, make sure the operand is the same each time. You already have v, so you don't need to look it up a second time from the map. And make sure you use the same type on both instanceOf calls.
Fix this by changing it to
if(v.isInstanceOf[mutable.Map[_, _]]){
maskRecursively(v.asInstanceOf[mutable.Map[String,Object]])
After some digging , i was able to solve this..
def maskJson(jsonStr: String): String = {
implicit val formats = org.json4s.DefaultFormats
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val result = mapper.readValue(jsonStr, classOf[Map[String, Object]])
val maskedJson = maskRecursively(result)
mapper.writeValueAsString(maskedJson)
}
def maskRecursively(map: Map[String, Object]): collection.mutable.Map[String, Object] = {
val mutable = collection.mutable.Map[String, Object]()
val maskColumns = PII_Data.getJsonPIIFields()
for ((k, v) <- map) {
if (v.isInstanceOf[Map[String, Object]]) {
mutable += k -> maskRecursively(v.asInstanceOf[Map[String, Object]])
} else if (v.isInstanceOf[List[Object]]) {
val list = v.asInstanceOf[List[Map[String, Object]]].map(i => maskRecursively(i)).toList
mutable += k -> list
} else {
if (maskColumns.contains(k)) {
mutable += (k -> "*****")
}
else {
mutable += k -> v
}
}
}
mutable
}

Break if value exists in JSON, but if value is null then return (kotlin)

I am trying to learn kotlin, and I came across a library called klaxon for parsing JSON. If the value I get from input is null, I want the program to keep repeating itself. Otherwise if the key does exist that I have inputted, I want the program to break. My program is not working how I would expect it to, though if I remove break, the program will loop forever even if the value is null.
Here is my code:
import java.net.*
import com.beust.klaxon.*
import java.util.*
import kotlin.text.*
fun webRequest(url: String) {
val uri = URL(url).readText()
val parser: Parser = Parser.default()
val stringBuilder: StringBuilder = StringBuilder(uri)
val json: JsonObject = parser.parse(stringBuilder) as JsonObject
println(json)
val input: String? = readLine()
do {
println(json)
if (input == null) {
println("value doesn't exist")
} else {
println(json.string(input))
break
}
} while (true)
}
fun main() {
webRequest("https://api.github.com")
}
You're reading input only once.
You should do readline() inside the loop to get desired behavior:
var input: String? = readLine()
while (input.isNullOrEmpty()) {
println("value doesn't exist")
input = readLine()
}
println(json.string(input))

Can I pass type information to simplify this somehow?

I have a lot of code like this, it is all the same except for the type PositionJson, it could be AnotherJson or FooJson or BarJson
Is there some way I can exctract all this code into one function that I can somehow pass into it the type? So that I don't have several of these big blocks of almost identical code littering my class?
I'm not sure if this is possible or not, just thought I'd ask because it would be nice to do...
/**
* #return the _open_ [PositionJson]s
*/
val positions: Array<PositionJson>?
#Throws(AccountsAPIException::class)
get() {
val service = constructServiceURL(POSITIONS, null, true)
try {
val messageJson = mapper.readValue<MessageJson<Array<PositionJson>>>(
callURL(service),
object: TypeReference<MessageJson<Array<PositionJson>>>() {
})
val error = messageJson.error
if (error != null) throw AccountsAPIException(error.errorCode, error.description)
return messageJson.data
} catch (e: Exception) {
throw AccountsAPIException(e)
}
}
You can do what you want with generics. However, to use generics we first need to extract that giant block of code into a method:
val positions: Array<PositionJson>? get() = getPositions()
fun getPositions(): Array<PositionJson>? {
...
}
We haven't solved the problem, but now we're in a position to be able to solve it by making getPositions generic (note that I also rename the function):
val positions: Array<PositionJson> get() = getArrayOf<PositionJson>()
// thanks to type inference I can omit the type on getArrayOf if desired:
val positions: Array<PositionJson> get() = getArrayOf()
fun <T> getArrayOf(): Array<T>? {
val service = constructServiceURL(POSITIONS, null, true)
try {
val messageJson = mapper.readValue<MessageJson<Array<T>>>(
callURL(service),
object: TypeReference<MessageJson<Array<T>>>() {
})
val error = messageJson.error
if (error != null) throw AccountsAPIException(error.errorCode, error.description)
return messageJson.data
} catch (e: Exception) {
throw AccountsAPIException(e)
}
}
Perfect! Except this won't compile thanks to type erasure. But we can fix this too by making the function inline and making the type parameter reified:
inline fun <reified T: Any> getArrayOf(): Array<T>? {
...
}
And that should do it. Now you can reuse this function as needed:
val positions: Array<PositionJson>? get() = getArrayOf()
val persons: Array<PersonJson>? get() = getArrayOf()
val bananas: Array<BananaJson>? get() = getArrayOf()
inline fun <reified T: Any> getArrayOf(): Array<T>? {
val service = constructServiceURL(POSITIONS, null, true)
try {
val messageJson = mapper.readValue<MessageJson<Array<T>>>(
callURL(service),
object: TypeReference<MessageJson<Array<T>>>() {
})
val error = messageJson.error
if (error != null) throw AccountsAPIException(error.errorCode, error.description)
return messageJson.data
} catch (e: Exception) {
throw AccountsAPIException(e)
}
}
One last thing: note that in all my examples I used property getters (get() = ...) as in your original code. However, I strongly suspect that you do NOT want to use a getter. Getters will be called every time someone accesses your property, which in this case means that every time someone reads the positions property you'll be calling constructServiceURL and making the service call, etc. If you want that code to only happen once then you should just call getArrayOf() once and assign the result to your property:
val positions: Array<PositionJson>? = getArrayOf()
// this syntax would also work:
val positions = getArrayOf<PositionJson>()

Accessing function defined within function in swift

Say I have a class NamedShape defined like this:
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
func containerFunc() -> Void{
println("strange world")
func subFunc() -> String {
return "sub function returns string"
}
println(subFunc())
}
}
I can initialize it like this:
let someNamedShape = NamedShape(name:"polynomial")
And invoke some method like this:
someNamedShape.containerFunc()
Now how can I invoke method subFunc within containerFunc on its object?
Compiler complains while trying this:
someNamedShape.containerFunc().subFunc()
It looks like it's not possible, unless you return the inner function from its containing function. Here's what the documentation says
Nested functions are hidden from the outside world by default, but can still be called and used by their enclosing function. An enclosing function can also return one of its nested functions to allow the nested function to be used in another scope.
This is how your code should look like in order to be able to call the subfunc
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
func containerFunc() -> (() -> String) {
println("strange world")
func subFunc() -> String {
return "sub function returns string"
}
println(subFunc())
return subFunc
}
}
let someNamedShape = NamedShape(name:"polynomial")
let subfunc = someNamedShape.containerFunc()
subfunc()

Converting nested lists to json gives superfluous arrays

I have some history data, that I want to convert to json. So these are Lists of lists. Their type is List[List[Position]] where Position is a simple case class. I wrote a formatter to help Json.toJson cope. I was expecting an output of exactly one outer array with two inner arrays that contain 3 objects each. What I got instead was this. Note the additional array wrappings.
[[[[{"amount":1.0,"minAmount":2.0,"price":3.0,"volume":4.0},
{"amount":5.0,"minAmount":6.0,"price":7.0,"volume":8.0},
{"amount":9.0,"minAmount":10.0,"price":11.0,"volume":12.0}]],
[[{"amount":0.1,"minAmount":0.2,"price":0.3,"volume":0.4},
{"amount":5.0,"minAmount":6.0,"price":7.0,"volume":8.0},
{"amount":9.0,"minAmount":10.0,"price":11.0,"volume":12.0}]]]]
I don't know where the wrapping arrays come from. Can somebody help me out here? This is a test with the wrapper I am using:
class ApplicationSpec extends Specification {
implicit object PositionFormat extends Format[List[List[Position]]] {
def writes(historyList: List[List[Position]]) : JsValue = {
Json.arr(historyList.map{
o => Json.arr(o.map{ p =>
Json.obj(
"amount" -> JsNumber(p.amount),
"minAmount" -> JsNumber(p.minAmount),
"price" -> JsNumber(p.price),
"volume" -> JsNumber(p.volume)
)
})
})
}
def reads(json: JsValue): JsResult[List[List[Position]]] = ???
}
"Application" should {
"Convert position data to json" in {
val l1 = ListBuffer(new Position(1.0D,2.0D,3.0D,4.0D),
new Position(5.0D,6.0D,7.0D,8.0D),
new Position(9.0D,10.0D,11.0D,12.0D)).toList
val l2 = ListBuffer(new Position(0.1D,0.2D,0.3D,0.4D),
new Position(5.0D,6.0D,7.0D,8.0D),
new Position(9.0D,10.0D,11.0D,12.0D)).toList
val obj = ListBuffer(l1,l2).toList
val json = Json.toJson(obj)
var string: String = json.toString()
println(string)
}
}
}
It seems that Json.arr takes it's arguments and returns a JsValue for a JSON array of them. It looks like you could simply do with Json.toJson:
Here's how arr is meant to be used:
// Json.arr
Json.arr("one", "two")
// Gives you
// play.api.libs.json.JsArray = ["one","two"]
If you instead do:
// vs
val l = List("one", "two")
Json.arr(l)
// Gives you
// play.api.libs.json.JsArray = [["one","two"]]
// ... a nested array, which is what you don't want.
What you need is:
// Json.toJson
Json.toJson(l)
// Gives you:
// play.api.libs.json.JsValue = ["one","two"]