what is monad by Haskell

楔子 Monad 是一個數學特性,來看看純的 Haskell 語言怎看待,使用「除法」來做一個簡單的示範說明。 Monads 這是一個 Haskell 基本的語法,宣告一個 Expre 的格式,他有可能是 Int (Val type) ,也有可能是 Div data Expr = Val Int | Div Expr Expr eval :: Expr -> Int eval (Val n) = n eval (Div x y) = eval x `div` eval y eval (Div (Val 1) (Val 0)) safediv :: Int -> Int -> Maybe Int safediv _ 0 = Nothing safediv n m = Just (n ‘div‘ m) eval :: Expr -> Maybe Int eval (Val n) = Just n eval (Div x y) = case eval x of Nothing -> Nothing Just n -> case eval y of Nothing -> Nothing Just m -> safediv n m eval :: Expr -> Maybe Int eval (Val n) = pure n eval (Div x y) = pure safediv <*> eval x <*> eval y (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b mx >>= f = case mx of Nothing -> Nothing Just x -> f x eval :: Expr -> Maybe Int eval (Val n) = Just n eval (Div x y) = eval x >>= \n -> eval y >>= \m -> safediv n m m1 >>= \x1 -> m2 >>= \x2 -> ....

May 26, 2022

useContext Provider Consumer

楔子 context 就語意上指的就是一個「環境」的概念,就如果轉成電腦來說就是「State」的意思。 而在 react component 有幾種情況可以夾帶這些「環境變數」 props state React 提供了另一個手法「context」來簡化語法 The Context API const LocaleContext = React.createContext(); LocaleContext 有二個屬性: Provider & Consumer Provider allows us to “declare the data that we want available throughout our component tree”. Consumer allows “any component in the component tree that needs that data to be able to subscribe to it”. Provider 提供一個 value 的 props <MyContext.Provider value={data}> <App /> </MyContext.Provider> 比較完整的 code // LocaleContext....

May 23, 2022

Arrow function generic types

楔子 Arrow Function 很常使用,但它的 Generic Type 有點不太好記,列舉一下幾種 Generic Arrow Functions 正常的函數 Generice Type 的格式 function firstOrNull<T>(arr: T[]): T | null { return arr.length === 0 ? null : arr[0]; } General const firstOrNull = <T>( arr: T[] ): T | null => arr.length === 0 ? null : arr[0]; Extends trick const firstOrNull = <T extends unknown>( arr: T[] ): T | null => arr.length === 0 ? null : arr[0]; Comma trick const firstOrNull = <T,>( arr: T[] ): T | null => arr....

May 22, 2022

Lambda Calculus

楔子 這是一個在計算機歷史用數學演化的方式,具有代表性的規律。 Lambda (λ) Calculus Function Abstraction 能夠用簡單的方式來呈現函數 λx.x^2 + 1 用 js 來表示 let res = x => x * x + 1 Function Application 何謂 β-reduction(beta reduction) ? 就是把「值」代入取得最後的計算結果 let res = (x => x * x + 1)(3) 但有些情況不符合 curry 的表示法 λxy.x*y 就應該轉換成 (λx.(λy.x*y)) 但其實 ( ) 是可以被簡化的 λx.λy.x*y 如果先代入一個數值 5 (λx.(λy.x*y)) (5) = (λy.5*y) 再代入 7 (λy.5*y)(7) = 35 用 javascript 來表示 function product(x, y) { return x * y; } product(5, 7) //retuns 35 // curry function product (x) { return function (y) { return x * y; } } 參考資料...

May 21, 2022

寫給想跳坑的 JS 新手(Part II): coding style

楔子 上一篇提到了 map filter reduce,這三個是最常見的也是最常用的使用方法,為了讓「程式碼」易讀,可以改造一下長相方便讓人看的懂在做什麼,至於怎做的就交給專業的人去優化改善就好。 所以先至少讓別人看的懂自已在寫的東西優先,試想看看,如果你是看 code 的人,「看的懂」vs 「要花一點點時間去細看」這二種,哪一種比較好讀? 先做到至少菜端出來看起來想吃,至於好不好吃就再說囉。嘿嘿嘿 程式碼的味道 用個最簡單的例子,把一個數字 x3 之後再 +1,但當數字是 5時就返回原值 f(1) = 1 * 3 + 1 f(5) = 5 來寫出這個 f 但我們用不同的長相來看看 撒尿牛丸全部攪在一起 這個應該是大部份的程式羅輯,就是把資料拆開來一個一個處理。 function f(x) { if(x !== 5) { return 3 * x + 1 } else { return x } } 點點點到天邊 這個 coding-style 就像你打開一個箱子把東西拿出來,「動作」後再放回去,依序處理。 let box = x => ({f: f => box(f(x)), x}) box(1) .f(multi3) .f(add1) // {f: ƒ f(), x: 4} box(5) ....

May 20, 2022

寫給想跳坑的 JS 新手(Part I): map filter reduce

楔子 身邊有些朋友有不少會想試著寫寫程式,常常坊間書翻一翻看到物件的東西,很快的就把書放下了,慢慢的也就失去興趣了。 但其實怎讓這些朋友開始可以有些動手做也能跑出一些結果,那種成就感會讓人慢慢的親近寫程式(coding),不可否認物件導向語言統治了軟體界,但光要先學會這個觀念可能就讓人却步了。 以前有部電影「張三峰」有句台詞,怎「張無忌」問,怎學會這部武功?「張三峰」說:「忘掉就好了」。 其實函數式語言的「入門」蠻簡單的,就像小時候的數學,函數吃一些變數,跑出來一個結果,用這個方式寫寫東西就可以做一些小實務的作品,也很有成就感。 就讓我們試試吧.. Declarative 宣告式 vs. Imperative 命令式 命令式(Imperative)白話文就是要用電腦的角度去思考,怎把答案做出來。 如果相要把一連串的資料去掉一些特定值(前提條件就要知道何謂 for-loop),示範的程式碼大概會長成下面的樣子 function filter(array) { let newArray = [] for (let index = 0; index < array.length; index++) { const element = array[index] if (element !== null && element !== undefined) { newArray[newArray.length] = element } } return newArray } // use case: filter([0, 1, undefined, 2, null, 3, 'four', '']) // [0, 1, 2, 3, 'four', ''] 但如果是所謂的宣告(Declarative)式,就是使用 filter 函數(知道 map/filter/reduce....

May 19, 2022

Monad Compose

楔子 今天再來進階一下改寫 Monad compose Monad 特徵 of: a => M(a) 也有人叫 lift 或 type lift map: map 的 f :: a => M(b) 會變成 M(M(b)) flatten: M(M(b)) => M(b) Monad 有 flapMap 的概念 flatMap = Map + flatten : f(a).flatMap(g) => M(b) const MyMonad = value => ({ flatMap: f => f(value), map (f) { return this.flatMap(a => Monad.of(f(a))), }, }) Monad.of = x => Monad(x) Monad(21).map( x => x * 2)....

May 18, 2022

Monad vs Promise

楔子 來試著說明何謂 monad 這其實是數學的一個名稱,但撇開那些艱深的道理,試試來用 Promise 的例子來說明看看。 Function Compose 最原始的 compose 的觀念就是把多個 function 做組合 const x = 20 const f = n => n * 2 const arr = Array.of(x) const result = arr.map(f) 例如 echo 就是吃二個參數回傳一個 function const echo = n => x => Array.from({length: n}).fill(x) console.log( [1,2,3].map( echo(3) ) ) 例如 flatMap 就是吃二個參數回傳一個 function const flatMap = (f, arr) => [].concat(...arr.map(f)) const echo = n => x => Array.from({length: n})....

May 17, 2022

lens laws

楔子 在 functional programming 中要進行對 store 的設定時,可以用 lens 的方式來進行設定,如果就像一個吸管直接定位來改變值,進行值也可以用函數來取代。 lens laws laws view(lens, set(lens, store, a)) = a 如果你改變了 store 某個值之後再立刻利用 lens 來取 store 的值,二個會相等(白話的意思就是你改變了 store 的值再拿出來看就是那個值) set(lens, b, set(lens, store, a)) = set(lens, b, store) 如果你改變了 store 的值為 a 又立馬改變值為 b,等同於直接改變值為 b(白話的意思就是你把一個值設了二次,最後的結果是第二次的值) set(lens, view(lens, store), store) = store 如果你用 lens 拿了某個值出來再同時 set 在 store 的 lens 位置的值,store 和原來的一致(白話文就是你取個 lens 的值拿出來的值再設到同一個 lens,該 store 維持不變) const view = (lens, store) => lens....

May 15, 2022

function mixins

楔子 在公司的專案開發中,程式總會愈長愈大,會慢慢的到了一個程度難以理解,在開發的過程中也慢慢開始把程式做一些模組化的動作。 在程式的抽像化過程中,應該有二大派系很當使用,就是物件導向 & 函數式編程。通常會蠻常出現二個關鍵字 繼承(inheritance) 組合(composition) Mixins “Favor object composition over class inheritance” the Gang of Four, “Design Patterns: Elements of Reusable Object Oriented Software” 有一種說法所謂的 mixins 就是像冰淇淋甜筒一樣,想吃什麼挖什麼口味,只要甜筒有那個味道功能,甜筒就只是一個載具而以。 Object composition 在 javascript 內,物件可以塞 function ,這時就要利用到 Object.assign 這個方法。 const chocolate = { hasChocolate: () => true } const caramelSwirl = { hasCaramelSwirl: () => true } const pecans = { hasPecans: () => true } const iceCream = Object.assign( {}, chocolate, caramelSwirl, pecans ) console....

May 13, 2022