optional - Possible to make use of Scala's Option flatMap method more concise? -
i'm admittedly new scala, , i'm having trouble syntactical sugar see in many scala examples. results in concise statement, far (for me) bit unreadable.
so wish take typical use of option class, safe-dereferencing, place start understanding, example, use of underscore in particular example i've seen.
i found nice article showing examples of use of option avoid case of null.
https://medium.com/@sinisalouc/demystifying-the-monad-in-scala-cc716bb6f534#.fhrljf7nl
he describes use so:
trait user { val child: option[user] }
by way, can write functions in-place lambda functions instead of defining them priori. code becomes this:
val result = userservice.loaduser("mike") .flatmap(user => user.child) .flatmap(user => user.child)
that looks great! maybe not concise 1 can in groovy, not bad.
so thought i'd try apply case trying solve.
i have type person
existence of person
optional, if have person, attributes guaranteed. reason, there no use of option
type within person
type itself.
the person
has pid of type id
. id
type consists of 2 string
types; id-type , id-value.
i've used scala console test following:
class id(val idcode : string, val idval : string) class person(val pid : id, val name : string) val anid: id = new id("passport_number", "12345") val person: person = new person(anid, "sean") val operson : option[person] = some(person)
ok. setup person , it's optional instance.
i learned above linked article persons id-val using flatmap; this:
val result = operson.flatmap(person => some(person.pid)).flatmap(pid => some(pid.idval)).getorelse("novalue")
great! works. , if infact have no person, result "novalue".
i used flatmap (and not map) because, unless misunderstand (and tests map incorrect) if use map have provide alternate or default person instance. didn't want have do.
ok, so, flatmap way go.
however, not concise statement. if writing in more of groovy style, guess i'd able this:
val result = person?.pid.idval
wow, that's bit nicer!
surely scala has means provide @ least nice groovy?
in above linked example, able make statement more concise using of syntactical sugar mentioned before. underscore:
or more concise:
val result = userservice.loaduser("mike") .flatmap(_.child) .flatmap(_.child)
so, seems in case underscore character allows skip specifying type (as type inferred) , replace underscore.
however, when try same thing example:
val result = operson.flatmap(some(_.pid)).flatmap(some(_.idval)).getorelse("novalue")
scala complains.
<console>:15: error: missing parameter type expanded function ((x$2) => x$2.idval) val result = operson.flatmap(some(_.pid)).flatmap(some(_.idval)).getorelse("novalue")
can me along here?
how misunderstanding this? there short-hand method of writing above lengthy statement? flatmap best way achieve after? or there better more concise and/or readable way ?
thanks in advance!
why insist on using flatmap? i'd use map
example instead:
val result = operson.map(_.pid).map(_.idval).getorelse("novalue")
or shorter:
val result = operson.map(_.pid.idval).getorelse("novalue")
you should use flatmap
functions return option
s. pid
, idval
s not option
s, map them instead.
you said
i have type person existence of person optional, if have person, attributes guaranteed. reason, there no use of option type within person type itself.
this essential difference between example , user
example. in user
example, both existence of user
instance, , child
field options. why, child
, need flatmap
. however, since in example, existence of person
not guaranteed, after you've retrieved option[person]
, can safely map of fields.
think of flatmap
map
, followed flatten
(hence name). if mapped on child:
val ouser = some(new user()) val child: option[option[user]] = ouser.map(_.child)
i end option[option[user]]
. need flatten single option
level, that's why use flatmap
in first place.
Comments
Post a Comment