4 ms·
I've recently interviewed at a startup that was into functional programming. The coding challenge was: transform a pair of an optional string and optional integ
by wrnr 7y ago
I've recently interviewed at a startup that was into functional programming. The coding challenge was: transform a pair of an optional string and optional integer, into a optional pair of string and integer. My solution was to just check if the left and right optional where present before creating the pair out of them. The solution they suggested was this double nested flatMap lambda contraption. Functional programming is a fun intellectual pursuit, but sometimes I wonder if its better to get your "I am smart" fix by reading maths or physics in the evening, and just do the boring imperative stuff at work.
- mruts 7y agoOnce you become familiar with monads and their operations, it becomes second nature. Going back from monadic operations to imperative code after tasting the forbidden fruit is awful. In someways functional programming has kind of ruined me as a developer: I would probably never take a job where I had to write in an imperative language full-time.
- pmontra 7y agoIn Elixir I would enumerate the cases with four definitions of the same function. Four lines of code, done. It looks similar to what you did. But I would tell them this is the simple and boring code I would run in production but probably not the smart code they want to see in the interview. Unfortunately smart code is often full of bugs and it costs more to deploy and maintain.
- yakshaving_jgt 7y agoWhy would you write four cases? You only care about two of the cases.
- UK-AL 7y agoUnless I'm not undersranding this correctly. This is basically 'zip' in most functional programming languages.
- almostzip 7y agoIndeed. However in Scala at least zip ends up giving you a List instead of an Option. for {} yield seems to do the trick scala> val a = Some("A") a: Some[String] = Some(A) scala> val b = Some(1) b: Some[Int] = Some(1) scala> val b2 = None b2: None.type = None scala> for { x <- a; y <- b } yield (x,y) res1: Option[(String, Int)] = Some((A,1)) scala> for { x <- a; y <- b2 } yield (x,y) res2: Option[(String, Nothing)] = None scala> a zip b res3: Iterable[(String, Int)] = List((A,1)) scala> a zip b2 res4: Iterable[(String, Nothing)] = List()
- agumonkey 7y agoDid you end up working there ? I'd suggest not to judge the idiom of their solution quickly. I understand it feels like a 20T hammer for a small nail. But it may be that they use a very high degree of function based programming composing abstraction rather than writing logic on atoms.
- yakshaving_jgt 7y agoI run a few startups on Haskell. Most of the work is boring imperative stuff. While it sounds like the company interviewing you were probing to see if you understand traversals and bifunctors, your proposed solution would have been given a thumbs up in code review on my team. FWIW, I would have written your function as f = bitraverse id id No "double nested flatMap lambda contraption" necessary. Ah, it looks like you can even just use `bisequence`, which is equivalent to `bitraverse id id`. So you didn't actually need to implement anything!
- tartrate 7y agoHaskell solution: uncurry $ liftA2 (,) edit: just noticed the other comment mentioning the better solution: bisequence
- jose_zap 7y agoThis is one of the solutions, using do notation: solve (theInt, theString) = do a <- theInt b <- theString return (a,b)
- kian 7y agowrnr - This is literally the 'flatmap' solution you referred to above, but in sugared form - what they were probably trying to see was whether or not you understood how to collapse a pair of Maybes into a single Nothing if either component is missing without needing to do an if test - i.e., whether or not you understand the essence of the bind operatorion in the context of the Maybe Monad.