Skip to content

Instantly share code, notes, and snippets.

View missingfaktor's full-sized avatar
🥔

Rahul Goma Phulore missingfaktor

🥔
View GitHub Profile
scala> trait A { type B }
defined trait A
scala> class Foo(val a: A)(val b: a.B)
<console>:12: error: not found: value a
class Foo(val a: A)(val b: a.B)
^
scala> case class Foo(a: A)(b: a.B)
<console>:12: error: not found: value a
abstract class Enum[E : Manifest] {
def all: Seq[E]
def asString: String
def fromString(string: String): Option[E] = {
all.find(_.asString == string)
}
}
abstract class TolerantEnum[E : Manifest] {

What I want, expressed in Haskell notation:

type Errors = [String]
type Warnings = [Keyword]

data ParseResult a = ParseSuccess a Warnings | ParseFailure Errors

My attempt at writing it in Typed Clojure:

user=> (use 'match-block.core)
nil
user=> (defn collect [pf xs]
#_=> (->> xs
#_=> (filter #(defined-at? pf %))
#_=> (map pf)))
#'user/collect
user=> (def sample-list
scala> def foo[R <: { def f1: Int }](x: R): (R, Int) = (x, x.f1)
foo: [R <: AnyRef{def f1: Int}](x: R)(R, Int)
scala> val x = new {
| def f1 = 90
| def f2 = "hello"
| }
x: AnyRef{def f1: Int; def f2: String} = $anon$1@adeb0ee
scala> foo(x)._1.f2
# Method references, with partial application.
class Array
def to_proc
lambda { |obj, *more_args| obj.send(*self, *more_args) }
end
end
# Sample use.
[3, 4, 9].map &[:+, 3]
data Person = Person { name :: String } deriving (Eq, Show)
let people = [ Person "Jacob", Person "Rubin", Person "Arjun" ]
sortBy (comparing name) people
-- [Person {name = "Arjun"},Person {name = "Jacob"},Person {name = "Rubin"}]
sortBy (comparing (Down . name)) people
-- [Person {name = "Rubin"},Person {name = "Jacob"},Person {name = "Arjun"}]

We receive JSON objects with hundreds of fields in them. About a dozen or so are utilized by business logic. The rest are useless, but need to be retained, because the JSONs massaged/enriched/amended by our system are later consumed by other systems.

Given the number of fields, converting JSONs to case classes is not an option.

Dealing with naked JSONs is also not an attractive option; need some way to attach domain meaning to it.

For this purpose, we use this thing called "embedded document" pattern. Fowler's post on the topic - http://martinfowler.com/bliki/EmbeddedDocument.html.

This is what it (roughly) looks like:

import net.liftweb.{json => L}
import play.api.libs.{json => P}
def liftJsonToPlayJson(liftJson: L.JValue): P.JsValue = liftJson match {
case L.JBool(b) => P.JsBoolean(b)
case L.JDouble(n) => P.JsNumber(n)
case L.JInt(n) => P.JsNumber(BigDecimal(n))
case L.JString(s) => P.JsString(s)
case L.JArray(values) => P.JsArray(values.map(liftJsonToPlayJson))
case L.JObject(fields) => P.JsObject(fields.map(f => f.name -> liftJsonToPlayJson(f.value)))
haskell> -- This is an attempt to distill a misunderstanding that pipe "operator" is just a
haskell> -- bad copy of OO dot.
haskell>
haskell> -- Let me define a pipe operator first. (Haskell doesn't ship with this by default.)
haskell> let (|>) = flip ($)
haskell>
haskell> -- A typical usage that looks like the "OO dot".
haskell> "hello" |> length
5
haskell> -- However such comparison is only superficial. With `|>`, the only constraint on the function