Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    callmekohei
    @callmekohei
    omanukeさん、すごい(≧∇≦)
    callmekohei
    @callmekohei

    <階乗進法 factorial number system をコンピュテーション式で表現することに関して>

    毎日毎日申し訳ありません。お手すきの時にでも。。。
    順列を求めたくて、階乗進法が必要になりました。
    .

    課題

    たとえば2桁の場合、下記のリストが欲しいです。
    N = 2 のとき
    [[0; 0];[0; 1];[1; 0];[1; 1];[2; 0];[2; 1]]

    下記コードにて実装しました。

    module test00 =
    
        type myBuilder () =
            member this.Bind (xs, f) = xs |> List.collect f
            member this.Return x = [x]
    
        let myBld = myBuilder()
    
        let N = 2
    
        let lst n =
            myBld { let! x = [ 0..n ]
                    let! y = [ 0..(n-1) ]
                    return [x; y] }
    
        for v in (lst N) do
            printfn "%A" v

    上記を実行すると

    [0; 0]
    [0; 1]
    [1; 0]
    [1; 1]
    [2; 0]
    [2; 1]

    ここで一つ問題が。。。桁を増やすとmyBldのところのコードを増やさないといけないです。たとえば3桁のばあいはmdBldは下記になります。

        let lst n =
            myBld { let! x = [ 0..n ]
                    let! y = [ 0..(n-1) ]
                    let! z = [ 0..(n-2) ]
                    return [x; y; z] }

    .
    .

    真の課題

    この myBld が直感ですが再帰っぽい感じがします。つまりなにかしら
    桁数がふえても同じ式で対応できるのではないかと考えました。

    なにかしらヒントを頂けると嬉しいです。

    adacola
    @adacola
    階乗進法って一種の位取りなので、お察しの通りループや再帰を使って一般化できます。
    階乗進法の作り方を調べてみるのがいいと思います。
    omanuke
    @omanuke
    コンピュテーション式はある枠組みの中にそって自由に記述できるものだと思うのですが、その階乗計算だと自由に記述する必要性あるんです?
    adacola
    @adacola
    コンピュテーション式を使うと嬉しい場面ではないような…(もちろん使うこと自体はできるでしょうけど)
    少なくとも自分が思いついた実装ではコンピュテーション式は出てこないです
    callmekohei
    @callmekohei

    omanukeさん、アダコーラさん。おはようございます!

    ううう、コンピュテーション式はなんか筋が悪そうな感じかも、、、ですね(^_^;; ループバージョンはできてるのでひとまず再帰バージョンを書いてみます。ただ、コンピュテーション式も興味はある、、、みたいな感じです。

    bleis-tift
    @bleis-tift
    ここでコンピュテーション式を説明したドキュメントを見てみましょう!
    F# のコンピュテーション式には、制御フローの構成要素と束縛を使用してシーケンス化および結合できる計算を記述するための便利な構文が用意されています。これらの計算式を使用すると、モナドの便利な構文が提供されます。モナドとは、関数型プログラムのデータ、制御、および副作用の管理に使用できる関数型プログラミングの機能です。
    最初の文からして意味不明です!

    原文は、

    Computation expressions in F# provide a convenient syntax for writing computations that can be sequenced and combined using control flow constructs and bindings.

    と、これまた何言ってるんだ感のある説明・・・
    コンピュテーション式つらい・・・
    訳してみた:
    F#のコンピュテーション式は、
    制御フローの構成要素や束縛を使って、
    並べたり組み合わせたりできる計算を書くための便利な構文を提供します。
    「並べたり組み合わせたりできる計算」を制御フローの構成要素(ifとかwhileとかそういうのとか、returnとか?)や束縛(let!てきな)を使って便利に書けるよ、ということが言いたいのだと推測
    bleis-tift
    @bleis-tift
    「並べたり組み合わせたりできる計算」ってなんぞや、に対する説明が吹っ飛んでるけど、これの一例が後ろの分で出てくる「モナド」ですね
    callmekohei
    @callmekohei
    ふむふむ、です(≧∇≦)なにか、コンピュテーション式でできそうですね!
    bleis-tift
    @bleis-tift
    階乗進法を実装するには、「並べたり組み合わせたりできる計算」は見つからないと思いますよー
    コンピュテーション式は、計算の実装ではなく、計算の枠組みを提供するものなので、計算の実装のために使っても意味ないというか、本来の使い方じゃないです
    callmekohei
    @callmekohei
    そ、そうなんですね ;^_^A
    bleis-tift
    @bleis-tift
    プログラムの構造を抽象化すると言いましょうか・・・
    モナドを勉強すれば、プログラムの構造の中にモナドを見いだせるようになりますよ多分
    その時こそ、コンピュテーション式の出番です
    callmekohei
    @callmekohei
    も、モナド!
    koheiさんのやりたいことと違うと思いますが、自分でも何をやってるか分からなくなってきたので放流します。
    callmekohei
    @callmekohei
    ガブさん、ありがとうございます!早速コード読み込みます!(≧∇≦)
    callmekohei
    @callmekohei
    しつこくてすみません (^_^;;
    下記コードのをmyBldに組み込むことってできたりしますか?
    これができると、個人的に嬉しいです。
    n = 3 のとき
    [0; 1; 2; 3]
    [0; 1; 2]
    [0; 1]
    let rec guruguru n acc =
        match n with
        | 0 -> acc
        | _ -> guruguru (n-1) ([0..n]::acc)
    
    for v in  guruguru 3 [] |> List.rev do
        printfn "%A" v
    bleis-tift
    @bleis-tift
    コンピュテーション式では、組み込む対象は関数ではなく、穴が開いた計算です。関数のどの部分を組み込みたいかが重要になります。
    ネスト構造などはコンピュテーション式に組み込みやすいですが、上記コードはネスト構造を持っているわけではないので、コンピュテーション式に組み込んでもありがたみはないでしょう。
    とりあえず、「どう書けると嬉しいか」を元に、それが実現できるかを考えたほうがいいですね
    callmekohei
    @callmekohei
    ブレイスさん!ありがとうございます!了解しました!(^_^)/
    bleis-tift
    @bleis-tift
    ココ向けに書いたら量が増えすぎたのでブログのエントリにした
    http://bleis-tift.hatenablog.com/entry/how-to-make-computation-expression
    callmekohei
    @callmekohei
    This message was deleted
    adacola
    @adacola
    ループ再帰副作用非使用で書いてみました。再帰使った実装はkoheiさん自身で書いてみてください。
    callmekohei
    @callmekohei
    ウォォォ。アダコーラさんのコード、キレイ!僕のループのコードとは段違いです (^_^;) すごく勉強になります!再帰は、、、かなり難しくて、、、。が、頑張ります!ありがとうございます(≧∇≦)
    callmekohei
    @callmekohei
    ちょっとまとめてみました!
    http://callmekohei00.hatenablog.com/entry/2016/03/18/010033
    callmekohei
    @callmekohei

    <文字をシフトさせてリストを作る作業に関して>

    連日の投稿大変すみません。お手すきの時にでも。。。
    .
    したいこと

    インデックスリスト [[0; 0]; [0; 1]; [1; 0]; [1; 1]; [2; 0]; [2; 1]]
    のときに文字リスト ["A";"B";"C"]を下記のようにしたい。
    インデックスリストは文字を左にシフトさせる数を表してます。
    
    index is [0; 0] : result ["A"; "B"; "C"]
    index is [0; 1] : result ["A"; "C"; "B"]
    index is [1; 0] : result ["B"; "A"; "C"]
    index is [1; 1] : result ["B"; "C"; "A"]
    index is [2; 0] : result ["C"; "A"; "B"]
    index is [2; 1] : result ["C"; "B"; "A"]

    いまできてること

    index is [0; 0] : result ["A"; "B"]
    index is [0; 1] : result ["A"; "C"]
    index is [1; 0] : result ["B"; "A"]
    index is [1; 1] : result ["B"; "C"]
    index is [2; 0] : result ["C"; "A"]
    index is [2; 1] : result ["C"; "B"]

    問題

    さいごの1文字が取り出せない
    test関数の x::xs のところあたりが問題のような気がしてます。

    コード

    let index = [[0; 0]; [0; 1]; [1; 0]; [1; 1]; [2; 0]; [2; 1]]
    let lst = ["A";"B";"C"]
    
    let f n lst = List.partition (fun x -> x = List.item n lst ) lst
    
    let rec test acc lst idx =
        match idx with
        | [] -> List.rev acc
        | x::xs -> 
            let l = f x lst
            test ((List.head (fst l)) :: acc)  (snd l) xs
    
    let mutable i = 0
    for v in index |> List.map (test [] lst) do
        printfn "index is %A : result %A" (List.item i index) v
        i <- i + 1
    omanuke
    @omanuke
    ざっとみですが、idxの長さ分からしかaccにたされてないから二文字でわ
    callmekohei
    @callmekohei
    うぐっ。。omanukeさん、なるほどです。で、できました〜。ありがとうございます〜!
    let rec test acc lst idx =
        match idx with
        | [] -> 
            List.rev ((List.head lst)::acc)
        | x::xs -> 
            let l = f x lst
            test ((List.head (fst l)) :: acc)  (snd l) xs
    omanuke
    @omanuke
    まーそこらへんはF#どうこうと言うよりもただのデバッグの話でインタラクティブなりでtestの中、printfデバッグしたら一発だと思うので、してから投げるでいいかとは思います(´・_・`)
    callmekohei
    @callmekohei
    すみません。。失礼しました(^_^;;;
    callmekohei
    @callmekohei
    皆様のお知恵を拝借して、書き上げました!パズルをとくための完全に個人的娯楽仕様です (^_^)/ 本当にありがとうございます!
    https://github.com/callmekohei/koffeefx/blob/master/src/puzzle.fsx
    // 内容
    powerset, combinations, permutations and repeated permutations
    callmekohei
    @callmekohei

    <クロージャにかんして>

    クロージャを理解するのに難儀してます。たとえば下記のF#のコードのクロージャが理解できません。

        let mult i lst = List.map ( fun x -> x * i ) lst
        mult 3 [1..5] |> printfn "%A"

    下記のjavascriptのコードだと理解できます。

        // javascript での実装
        function makeAdder ( captured ) {
            return function ( free ) {
                return free + captured
            }
        }
    
        var add10 = makeAdder (10)
        add10 (32) // 42

    このjavascriptのコードをF#で書き直すとどうなりますでしょうか?トライしましたが書けませんでした。お知恵を拝借できると嬉しいです。

    Kouji Matsui
    @kekyo
    > let makeAdder captured = fun free -> free + captured
    ;;
    
    val makeAdder : captured:int -> free:int -> int
    
    > makeAdder 10
    ;;
    val it : (int -> int) = <fun:it@3>
    > let add10 = makeAdder 10
    ;;
    
    val add10 : (int -> int)
    
    > add10 32;;
    val it : int = 42
    >
    とか?
    callmekohei
    @callmekohei
    kekyoさん!ありがとうございます!理解できました!ということは前のF#コードのicapturedという理解です!
        let mult captured lst = List.map ( fun x -> x * captured) lst
        mult 3 [1..5] |> printfn "%A"
    Kouji Matsui
    @kekyo
    右から左に置き換えてみたんですが、問題点が合っていて良かった。jsのクロージャは良く問題にしてる人がいるけど、実は何が問題なのかわかってない...
    callmekohei
    @callmekohei

    <アクティブパターンに関して>

    下記コードプログラミングF#の179ページにエラーになるコードとして掲載されてるのですが、このコードをアクティブパターンにしたいと思いトライしましたが、できませんでした。ヒント頂けると嬉しいです。
        // エラーになる ( programming F# p179 )
        let containsVowel (word: string) =
            let letter = word.Chars
            match letter with
            | ContainsAny ['a';'e';'i';'o';'u'] -> true
            | Sometimescontains ['y'] -> true
            | _ -> false
    // 自分で考えてみたコード
        let (|'a'|'e'|'i'|'o'|'u'|) ( word: string ) = 
            match word.Chars with
            |'a'|'e'|'i'|'o'|'u' -> true
            | _ -> false