[Struktur Aljabar] functionM / Power Query M (Filter & Sort)
Jangan jadi Bodoh karena orang bangun dengan perasaan yang berbeda setiap harinya
Ide untuk melakukan sorting atau filtering adalah dengan membuat predicate. Dimana predicate merupakan fuction type A yang akan mereturn Boolean. Untuk itu kita perlu mendefinisikan typealias Predicate.
typealias Predicate<A> = FunctionM<A, Bool>
Maksudnya kita dapat take function apapun dan selalu me-return Boolean.
Nah untuk melakukan hal tersebut apa itu functionM ?
Saya coba cari definisi functionM dan berakhir pada Power Query M formula punya Microsoft, nggak tau mereka adalah benda yang sama atau kebetulan punya definisi yang mirip yaitu
A core capability of Power Query is to filter and combine, that is, to mash-up data from one or more of a rich collection of supported data sources.
In the Power Query M formula language, a function is a mapping from a set of input values to a single output value
Untuk mefilter dan menggabungkan dengan cara memapping set input value menjadi satu output value.
Saya nggak mengiyakan atau sebaliknya kalo functionM disini adalah Power Query M tapi karena mempunyai tujuan yang sama jadi saya masukan ke sini untuk kita ulik lebih dalam lagi selanjutnya.
Oke kembali lagi ke functionM tadi jadi bagaimana bentuk functionM ini ?jadi functionM ini juga inherit dari Monoid.
struct FunctionM<A, M: Monoid>: Monoid {
let call: (A) -> M static var e: FunctionM {
return FunctionM { _ in M.e }
} static func <> (lhs: FunctionM, rhs: FunctionM) -> FunctionM {
return FunctionM { a in
return lhs.call(a) <> rhs.call(a)
}
}
}
Lets check our code
let isEven = Predicate<Int> { $0 % 2 == 0 }func isLessThan<C: Comparable>(_ c: C) -> Predicate<C> {
return Predicate { $0 < c }
}
Filter
Selanjutnya masuk ke filter array
extension Array {
func filtered(by predicate: Predicate<Element>) -> [Element] {
return self.filter(predicate.call)
}
}[2,3,4].filtered(by: isEven <> isLessThan(10)) // result 2,4
Concat
[2,3,4].filtered(by: concat([isEven, isLessThan(10)]))
Ordering
enum Ordering: Monoid {
case lt
case eq
case gt
static var e: Ordering {
return .eq
}
static func <> (lhs: Ordering, rhs: Ordering) -> Ordering {
switch (lhs, rhs) {
case (.lt, _): return .lt
case (.gt, _): return .gt
case (.eq, _): return rhs
}
}
}typealias Comparator<A> = FunctionM<(A, A), Ordering>extension Comparable {
static func comparator() -> Comparator<Self> {
return Comparator { lhs, rhs in
return lhs < rhs ? .lt : lhs > rhs ? .gt : .eq
}
}
}extension Array {
func sorted(by comparator: Comparator<Element>) -> Array {
return self.sorted { comparator.call(($0, $1)) == .lt }
}
}[1,4,6,3].sorted(by: Int.comparator()) // result 1,3,4,6 ------------
[REVERSED]extension Ordering {
func reversed() -> Ordering {
return self == .lt ? .gt : self == .gt ? .lt : .eq
}
}extension FunctionM where M == Ordering {
func reversed() -> FunctionM {
return FunctionM { self.call($0).reversed() }
}
}
Whats Next ?
Selanjutnya mungkin kita akan masuk Lenses dan Prism :). Semoga membantu !!!!!!