查看完整版本 : Practice Functional Programming With C# 2

form5 2017-12-11 12:10 AM

Practice Functional Programming With C# 2

map vs  bind in Layumba library[code]class Program
{
    static Func < int, bool > IsValidNumber = i => i % 2 == 0;
    static Func < int, Option < bool > > IsValidNumber2 = i => i % 2 == 0;

    static Func < Option < int >, Option < bool > > IsValidNumber3 = i => i.Map(IsValidNumber);


    static void TestMap()
    {
        var opt = F.Some(10)
       .Map(IsValidNumber);

        var opt2 = F.None
                    .Map(IsValidNumber);


        var opt3 = F.Some(10)
                    .Map(IsValidNumber2);

        var opt4 = F.None
                    .Map(IsValidNumber2);

        Console.WriteLine(opt); // Some(True)
        Console.WriteLine(opt2); // None

        Console.WriteLine(opt3); // Some(Some(True))
        Console.WriteLine(opt4); // None
    }

    static void TestBind()
    {
        Option < int > opt = F.Some(10);

        var r = opt.Bind(IsValidNumber2);
        //var r2 = opt.Bind(IsValidNumber3); //fail to compile

        Console.WriteLine(r); // Some(True)
        //Console.WriteLine(r2); // Some(True)
    }


    static void Main(string[] args)
    {
        TestMap();
        TestBind();
    }
}  [/code]I'm surprised that "opt.Bind(IsValidNumber3)" won't work. :smile_14:

[[i] 本帖最後由 form5 於 2017-12-11 12:14 AM 編輯 [/i]]

Susan﹏汪汪 2017-12-11 08:14 AM

int和Option< int >不同type

fitcat07 2017-12-11 10:07 AM

試下用 Some(Some(10)).Bind(IsValidNumber3)

xianrenb 2017-12-11 01:11 PM

[quote]原帖由 [i]form5[/i] 於 2017-12-11 12:10 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472207877&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
map vs  bind in Layumba libraryclass Program
{
    static Func < int, bool > IsValidNumber = i => i % 2 == 0;
    static Func < int, Option < bool > > IsValidNumber2 = i => i % 2 == 0;

    stati ... [/quote]

以下都是估估下。

TestMap() 全部過到 compile ,可能是因為 map none 已經自動出 none :
[url=https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/option.map%5B%27t,%27u%5D-function-%5Bfsharp%5D]https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/option.map%5B%27t,%27u%5D-function-%5Bfsharp%5D[/url]
即是內部會自動 check 是否 int 。
如果是 int ,就用 user define 的東西。
如果是 none ,就用 language 已 define 的 map 。
再將兩個 result combine ,得出最後答案。

Testbind() 中的 r , 經 IsValidNumber2 前自動 cast 做 int ,所以出到 Some(true) 。
r2 就不同,經 IsValidNumber3 前自動 cast 做 Option < int > ,但內裏卻用 IsValidNumber ,只接受 int ,所以就 compile error 。

Susan﹏汪汪 2017-12-11 01:22 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-11 01:11 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472228727&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


以下都是估估下。

TestMap() 全部過到 compile ,可能是因為 map none 已經自動出 none :
https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/option.map%5B%27t,%27u%5D-function-%5Bfsharp%5 ... [/quote]
冇咁複雜

Map是食(T) -> Result的function 、輸出Result?
Bind是食(T) -> Result?的function、輸出Result?

IsValidNumber是(int) -> bool
IsValidNumber2是(int) -> bool?
IsValidNumber3是(int?) -> bool?

IsValidNumber放入Map就會得到bool?
IsValidNumber2放入Map就會得到bool??
IsValidNumber2放入Bind就得到bool?
IsValidNumber3根本唔乎合Map同Bind的argument type

但可以咁做IsValidNumber3(opt)

Susan﹏汪汪 2017-12-11 01:43 PM

其實Map同Bind完全唔難理解
個implements 都好直觀

Swift的map同flatMap對應就是前面C#的Map同Bind

汪汪直接post swift的source code
https://github.com/apple/swift/blob/master/stdlib/public/core/Optional.swift

xianrenb 2017-12-11 01:54 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-11 01:22 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472229223&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

冇咁複雜

Map是食(T) -> Result的function 、輸出Result?
Bind是食(T) -> Result?的function、輸出Result?

IsValidNumber是(int) -> bool
IsValidNumber2是(int) -> bool?
IsValidNumber3是(int?) -> bool?

IsVa ... [/quote]

這樣看來說不通。
當個 Result 是 (bool?) 就得,當 T 是 (int?) 就唔得,前後不一致。

Susan﹏汪汪 2017-12-11 01:58 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-11 01:54 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472230637&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


這樣看來說不通。
當個 Result 是 (bool?) 就得,當 T 是 (int?) 就唔得,前後不一致。 [/quote]
個T不是放入去的function 去決定
汪汪前面唔應該打T

用swift的source code去睇

Wrapped即是汪汪前面的T
Optional<Wrapped>有呢兩個methods
[code]
public func map<U>(
    _ transform: (Wrapped) throws -> U
  ) rethrows -> U?
[/code]

[code]
public func flatMap<U>(
    _ transform: (Wrapped) throws -> U?
  ) rethrows -> U?[/code]

xianrenb 2017-12-11 06:43 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-11 01:58 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472230843&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

個T不是放入去的function 去決定
汪汪前面唔應該打T

用swift的source code去睇

Wrapped即是汪汪前面的T
Optional有呢兩個methods

public func map(
    _ transform: (Wrapped) throws -> U
  ) rethrows -> U?  ... [/quote]

我唔熟 Swift 。
約略看了:
[url=https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html]https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html[/url]
[url=https://stackoverflow.com/questions/30876068/what-is-in-swift-telling-me]https://stackoverflow.com/questions/30876068/what-is-in-swift-telling-me[/url]

[url=https://developer.apple.com/documentation/swift/array/2908681-map]https://developer.apple.com/documentation/swift/array/2908681-map[/url]
以我的理解,你說的 Optional<Wrapped> 中的 map ,都是輸入一個內部名叫 transform 的 function , function type 為 (輸入 type (Wrapped) ,可 throw error , 輸出 type 為 U ),而 map 可 rethrow error , 輸出 type 為 U? 。

那麼,應該無規定 U 能不能是 bool? ,或者 Wrapped 能不能是 int? 。

而前面一樓都有 Some(Some(True)) ,證明可容許多層 Optional 效果, Some(Some(True)) 不等於 Some(True) 。

Susan﹏汪汪 2017-12-11 07:22 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-11 06:43 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472244780&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


我唔熟 Swift 。
約略看了:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html
https://stackoverflow.com/questions/30876068/ ... [/quote]
transform的Wrapped一定係跟Optional<Wrapped>本身的Wrapped

即係如果你寫
var opt : Int? = .some(5)
opt.map { ... }

呢到的Wrapped就是Int
因為opt是Optional<Int>

U係result type、不一定是bool
跟你提供的transform的result type

Susan﹏汪汪 2017-12-11 07:24 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-11 06:43 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472244780&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


我唔熟 Swift 。
約略看了:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html
https://stackoverflow.com/questions/30876068/ ... [/quote]
Optional可以係多層

汪汪前面#5提過bool??
就即是Optional<Optional<bool>>

[[i] 本帖最後由 Susan﹏汪汪 於 2017-12-11 07:26 PM 編輯 [/i]]

form5 2017-12-11 09:30 PM

From the signature of Bind :
   
public static Option < R > Bind < T, R > (this Option < T > optT, Func < T, Option < R > > f );

if
  T is Option< T '>
then
  Some(Some(10)).Bind(IsValidNumber3);// fine

if
  T is int
then
  Some(10).Bind(IsValidNumber2); // fine

form5 2017-12-11 09:35 PM

[quote]原帖由 [i]fitcat07[/i] 於 2017-12-11 10:07 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472220037&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
試下用 Some(Some(10)).Bind(IsValidNumber3) [/quote]

吾知Haskell個Bind 係吾係這樣呢了?

[[i] 本帖最後由 form5 於 2017-12-11 09:37 PM 編輯 [/i]]

form5 2017-12-11 09:50 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-11 01:22 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472229223&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
冇咁複雜
Map是食(T) -> Result的function 、輸出Result?
Bind是食(T) -> Result?的function、輸出Result?

IsValidNumber是(int) -> bool
IsValidNumber2是(int) -> bool?
IsValidNumber3是(int?) -> bool?
IsVa ... [/quote]
可以自己再係Option type 加 Bind extension 令佢直接Bind到 IsValidNumber3,但問題係 吾知 係吾係正确做法?

Susan﹏汪汪 2017-12-11 10:03 PM

[quote]原帖由 [i]form5[/i] 於 2017-12-11 09:50 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472253560&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]

可以自己再係Option type 加 Bind extension 令佢直接Bind到 IsValidNumber3,但問題係 吾知 係吾係正确做法? [/quote]
邏輯上可以咁做
但唔實用

因為IsValidNumber3本身可以食optional
即可以就咁IsValidNumber3(opt)

Bind呢個keyword係借Haskell
Haskell 個版本都一樣係食(T) -> U?
或者(T) -> [U]

Swift改左個名做flatMap易明好多
因為例如
[code]
func g1(_ x: Int) -> [Int] {
    return Array(0..<x)
}

var array = [1, 2, 3]

array.map(g1)   //    [[0], [0, 1], [0, 1, 2]]
array.flatMap(g1)    //    [0, 0, 1, 0, 1, 2]

[/code]

flatMap 個意思就是flatten mapping

Susan﹏汪汪 2017-12-11 10:07 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-11 10:03 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472254133&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]

邏輯上可以咁做
但唔實用

因為IsValidNumber3本身可以食optional
即可以就咁IsValidNumber3(opt)

Bind呢個keyword係借Haskell
Haskell 個版本都一樣係食(T) -> U?
或者(T) ->

Swift改左個名做flatMap易明好多
... [/quote]
只要把optional 睇成zero or one element 的array

就會明白點解用map會出現左兩層optional 的result

form5 2017-12-11 11:16 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-11 10:03 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472254133&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

邏輯上可以咁做
但唔實用

因為IsValidNumber3本身可以食optional
即可以就咁IsValidNumber3(opt)
Bind呢個keyword係借Haskell
Haskell 個版本都一樣係食(T) -> U?
或者(T) ->

Swift改左個名做flatMap易明好多
... [/quote]
嗯, IsValidNumber3 可以 由二個step , 拆左 第一個argument value, 然後再用map

[[i] 本帖最後由 form5 於 2017-12-11 11:17 PM 編輯 [/i]]

xianrenb 2017-12-12 08:30 AM

[quote]原帖由 [i]form5[/i] 於 2017-12-11 09:30 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472252579&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
From the signature of Bind :
   
public static Option < R > Bind < T, R > (this Option < T > optT, Func < T, Option < R > > f );

if
  T is Option< T '>
then
  Some(Some(10)).Bind(IsValidNum ... [/quote]

我真的是太耐無寫過 static typing language 的 code ,經驗不足。
之前我的估計錯了。
想來 static typing language 在 call method 時出 compile-time error ,不是 syntax error 的話,大概就只會是類似 type mismatch 的情況。
樓主又故意不說 error message 是什麼,所以我就估錯了。

另一方面,在我看來,這個 bind 在 language 中的定義看來很有問題。
不查資料的話, concept 上大概一般人都會估個 object 是什麼 type ,就可以 bind 到一個 function 是食相關 type 的。
樓主原本的 code 表現的情況也是如此吧?
點估到一定要 bind 個 function 少一層 Option 才可以呢!

[[i] 本帖最後由 xianrenb 於 2017-12-12 08:31 AM 編輯 [/i]]

Susan﹏汪汪 2017-12-12 10:23 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-12 08:30 AM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472266011&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


我真的是太耐無寫過 static typing language 的 code ,經驗不足。
之前我的估計錯了。
想來 static typing language 在 call method 時出 compile-time error ,不是 syntax error 的話,大概就只會是類似 ty ... [/quote]
因為呢個係一個monad

fitcat07 2017-12-12 11:16 AM

[quote]原帖由 [i]form5[/i] 於 2017-12-11 09:35 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472252852&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
吾知Haskell個Bind 係吾係這樣呢了? [/quote]
Bind等同Haskell嘅>>=(如先用function開頭,像C#,更貼切係=<<)。
Map等同fmap或< $ >。

以下係講Functor, Applicative and Monad鏈結,雖然用Haskell做例子,但係好多圖,解釋好清楚:[url=http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html]Functors, Applicatives, And Monads in Pictures[/url]

[[i] 本帖最後由 fitcat07 於 2017-12-12 11:28 AM 編輯 [/i]]

xianrenb 2017-12-12 11:56 AM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-12 10:23 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472270365&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

因為呢個係一個monad [/quote]

之前無學過 monad ,只接觸過 JavaScript 中的 bind() ,所以完全理解唔到點解前面說的 bind 要唔同 type 。
那麼就更簡單了,樓主的 code 一開始就 concept 錯了。
用 bind 一定要兩個 type 不同,輸入個 function 一定要少一層 type 。

xianrenb 2017-12-12 12:08 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-12 11:56 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472274342&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


之前無學過 monad ,只接觸過 JavaScript 中的 bind() ,所以完全理解唔到點解前面說的 bind 要唔同 type 。
那麼就更簡單了,樓主的 code 一開始就 concept 錯了。
用 bind 一定要兩個 type 不同,輸入個 fun ... [/quote]

不過這樣看的話,就變成 JavaScript 的 bind() 是錯誤定義了?

Susan﹏汪汪 2017-12-12 12:21 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-12 12:08 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=472274814&ptid=27114722][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


不過這樣看的話,就變成 JavaScript 的 bind() 是錯誤定義了? [/quote]
冇搞錯的話

Javascript 的bind不是前面一直討論的bind

而係arguments binding

xianrenb 2017-12-12 12:46 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-12-12 12:21 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472275152&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

冇搞錯的話

Javascript 的bind不是前面一直討論的bind

而係arguments binding [/quote]

應該是接近的 concept ,但當然不同,否則之前我不會說 JavaScript 的 bind 這樣看是錯了。
[url=https://stackoverflow.com/questions/22115472/binding-functions-that-take-multiple-arguments]https://stackoverflow.com/questions/22115472/binding-functions-that-take-multiple-arguments[/url]
[quote]...After reading some very basic haskell now I know how to "chain" monadic actions using bind, like:

echo = getLine >>= putStrLn
(>>=) operator is very handy in this fashion, but what if I want to chain monadic actions (or functors) that take multiple arguments?...[/quote]
我的理解是把 getLine 變成 putStrln 的“argument”來組成一個新 function 叫 echo 。
如果是 JavaScript ,可能會是:
echo = putStrLn.bind(getLine)
咁上下。
如果 getLine 不是 function 而是某種 data ,兩樣東西就應該非常相似。

form5 2017-12-12 11:35 PM

[quote]原帖由 [i]fitcat07[/i] 於 2017-12-12 11:16 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472272588&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

Bind等同Haskell嘅>>=(如先用function開頭,像C#,更貼切係= [/quote]
Thanks,  great pictures :smile_o12:

form5 2017-12-12 11:44 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-12-12 11:56 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=472274342&ptid=27114722][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
...樓主的 code 一開始就 concept 錯了。
...
[/quote]
:smile_46:
頁: [1]
查看完整版本: Practice Functional Programming With C# 2