Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Yukitoshi Suzuki
    @yukitos
    事前登録特典は特にありません :P
    githubでPRベースで申請してもらう予定なのですが、事前登録のほうがコンフリクトしづらいというだけです。
    Kouji Matsui
    @kekyo
    ちょうひよっこだけど入ってみました
    Yukitoshi Suzuki
    @yukitos
    ありがとうございます!
    Kouji Matsui
    @kekyo
    Parameterized active recognizerって、Partialしかありえない? うまく書けなかった...
    
    let (|ContainsAny|_|) chars input =
      match input |> String.exists (fun strch -> chars |> Seq.exists (fun ch -> strch = ch)) with
      | true -> Some input
      | false -> None
    
    [<EntryPoint>]
    let main argv = 
        let str = "hoge"
        let result =
            match str with
            | ContainsAny ['a';'e';'i';'o';'u'] _ -> true
            | _ -> false
    
        printfn "%A" result
    
        0
    結果要らないんだけどなぁ
    adacola
    @adacola
    let (|Mimorin|) x (y : string) = if x = "mimorin" then Mimorin (y.ToUpper()) else Mimorin y
    match "umi" with Mimorin "mimorin" x -> x
    
    val ( |Mimorin| ) : x:string -> y:string -> string
    val it : string = "UMI"
    Partialじゃなくてもいけました
    callmekohei
    @callmekohei
    できました〜。ってみなさん、できてる〜(^_^)/ マイクロソフトのホームページに載ってた正規表現の分を使って書きました〜
    open System.Text.RegularExpressions
    
    module Test =
    
        let (|ParseRegex|_|) regex str =
            let m = Regex(regex).Match(str)
            if m.Success then 
                Some (List.tail [ for x in m.Groups -> x.Value ])
            else
                None
    
        let parseString str =
            match str with
            | ParseRegex "a|e|i|o|u" str -> true
            | _ -> false
    
        parseString "abc" |> printfn "%A" // true
        parseString "efg" |> printfn "%A" // true
        parseString "ijk" |> printfn "%A" // true
        parseString "opq" |> printfn "%A" // true
        parseString "uxy" |> printfn "%A" // true
        parseString "zzz" |> printfn "%A" // false
    partial にしないと警告がでました〜
     warning FS0026: This rule will never be matched
    adacola
    @adacola
    結果がいらないのであれば
    let (|Mimorin|_|) x (y : string) = if x = "mimorin" && y = "umi" then Some() else None
    match "umi" with Mimorin "mimorin" -> true | _ -> false
    みたいに書けます
    callmekohei
    @callmekohei

    kekyoさん。
    なぜに、

    ContainsAny ['a';'e';'i';'o';'u'] _

    と アンダースコアなんでしょ?

    ContainsAny ['a';'e';'i';'o';'u'] str

    のような気が、、、

    Kouji Matsui
    @kekyo
    そこにstrと書いたら、本の例のようにならないので... 本当は _ も無しにしたかった
    Some unitだと省略できるのか...
    callmekohei
    @callmekohei
    kekyoさん。なるほどです!
    Kouji Matsui
    @kekyo
    これはつまりやっぱりPartialにしかならないってことかな
    bleis-tift
    @bleis-tift
    Letter でやる例
      let (|Letter|_|) (ch: char) (word: string) =
        if word.Contains(string ch) then Some () else None
    
      let containsVowel (word: string) =
        match word with
        | Letter 'a'
        | Letter 'e'
        | Letter 'i'
        | Letter 'o'
        | Letter 'u' -> true
        | _ -> false
    LetterよりもContainsLetterとかHasLetterとかの方が名前としてはいいかも?
    アクティブパターンの名前、いつも迷う
    callmekohei
    @callmekohei
    ブレイスさん!word.Containsというのがあるんですね!これは便利!
    bleis-tift
    @bleis-tift
    もっと絞って、ContainsとかHasとかにしてしまうのもアリか・・・
    汎用的すぎてアレかもしれないけど
    Kouji Matsui
    @kekyo
    ここまでわかれば:
    let (|ContainsAny|_|) chars (input: string) =
      match input.IndexOfAny(chars |> Seq.toArray) with
      | -1 -> None
      | _ -> Some()
    bleis-tift
    @bleis-tift
    ちなみに:Some ()の部分は、Some パーシャルアクティブパターン名でも可
    もっと言うと:Some (パーシャルアクティブパターン名())でも可
    後者でもいいのは今知った
    adacola
    @adacola
    let (|ContainsAny|) chars input =
        match input |> String.exists (fun strch -> chars |> Seq.exists (fun ch -> strch = ch)) with
        | true -> ContainsAny
        | false -> failwith "なかった"
    
    let str = "hoge"
    match str with
    | ContainsAny ['h'] -> printfn "あった"
    
    ~vsE08A.fsx(8,15): error FS0001: この式に必要な型は
        string -> unit    
    ですが、ここでは次の型が指定されています
        'a list
    Partialじゃないと結果省略しようとするとコンパイルエラーになりますね…
    Kouji Matsui
    @kekyo
    :+1:
    adacola
    @adacola
    ContainsAny返すところを()にしたりContainsAny()にしたりしてみたけどだめでした
    Kouji Matsui
    @kekyo
    判別共用体を返しているイメージ?
    でも型はunit optionなんだ。どういう解釈なのか...
    adacola
    @adacola
    型は
    選択肢1つしかないパターン=unit、選択肢2つ以上あるパターン=Choice、Partialパターン=option
    になってますね
    Kouji Matsui
    @kekyo

    IL見たら、FSharpOption<unit>がnullかどうかで判断してるので、仮にPartialじゃなく書けたとしてもそれほど影響はないってことがわかりました

    public static int main(string[] argv)
    {
        string str = "hoge";
        string text = str;
        FSharpList<char> fSharpList = FSharpList<char>.Cons('a', FSharpList<char>.Cons('e', FSharpList<char>.Cons('i', FSharpList<char>.Cons('o', FSharpList<char>.Cons('u', FSharpList<char>.Empty)))));
        string input = text;
        FSharpOption<Unit> fSharpOption = Program.|ContainsAny|_|((IEnumerable<char>)fSharpList, input);
        bool result = fSharpOption != null;
        FSharpFunc<bool, Unit> fSharpFunc = ExtraTopLevelOperators.PrintFormatLine<FSharpFunc<bool, Unit>>(new PrintfFormat<FSharpFunc<bool, Unit>, TextWriter, Unit, Unit, bool>("%A"));
        bool func = result;
        fSharpFunc.Invoke(func);
        return 0;
    }

    行ける、行けるでー

    char listのコストのほうが気になる
    callmekohei
    @callmekohei
    ブレイスさんの分、下記みたいにしたいのですが、可能ですか?
    module Test =
    
        let (|ContainsAny|_|) ( ch: char ) ( word: string ) =
            if word.Contains ( string ch ) then Some () else None
    
        let containsVowel = function
            | ContainsAny  ["a";"e";"i";"o";"u"] -> true
            | _ -> false
    
        containsVowel "abc" |> printfn "%A"
    bleis-tift
    @bleis-tift
    型が合いませんよ
    ch: charじゃなくてss: string seqにして、Containsを直接使わずにSeq.existsかませれば行けます
      let (|ContainsAny|_|) (cs: char seq) (word: string) =
        if cs |> Seq.exists (string >> word.Contains) then Some () else None
    
      let containsVowel (word: string) =
        match word with
        | ContainsAny "aeiou" -> true
        | _ -> false
    stringchar seqであることを使ったバージョン
    callmekohei
    @callmekohei

    ブレイスさん!ありがとうございます!

    cs |> Seq.exists (string >> word.Contains)

    ここの処理がわからなくて、、、。美しいです!

    callmekohei
    @callmekohei
    ちょっとアクティブパターンについてまとめました!
    http://callmekohei00.hatenablog.com/entry/2016/03/25/161246
    callmekohei
    @callmekohei

    <Mixinについて>

    ホームページみてたらmixinなる面白いの見つけました。
    https://fsharpforfunandprofit.com/posts/completeness-seamless-dotnet-interop/
    で、ちょっと前にはやった世界のナベアツmixinを使ってやってみようとおもいました。よければお手すきの時にでも。。。

    
    module SekaiNoNabeatu =
    
        type IAnimal = 
            abstract member Say : unit -> string
    
        let say (animal:IAnimal) = 
            animal.Say () |> printfn "%s" 
    
        type Geinin = Nabeatu
    
        type Geinin with
            member this.AsAnimal = 
                    { new IAnimal with member a.Say () = "test" }
    
        let geinin = Nabeatu
    
        [1..10] |> List.iter ( fun n -> say (geinin.AsAnimal ))

    いまできてることはtestを10回連続で表示させることだけです。この考え方でFizzBuzzのように3,5そして15のときtest3, test5そしてtest15と表示させることはできますでしょうか?ヒントを頂けると嬉しいです (^_^)

    MIYAZAKI Shohei
    @hafuu
    これ、世間で言う mixin じゃなくて mixing では?
    ただ既存のF#の型とインターフェイスを混ぜて使う時のアレコレなだけに見えますが
    それは置いておいて、test3, test5とかの表示は、
    fun n -> say (geinin.AsAnimal )の部分でif式書けばよいのでは
    Kouji Matsui
    @kekyo
    動物はみんなsayする、ナベアツだけが3の時(10も?)に特別なので、mixin?するAsAnimalの実装の所で、現在の数に応じて返される文字列を変えればいいと思うんですが、sayに現在の数を渡すというのはあまりスマートではない気が... (動物全体にとって、現在の数に興味があるようには思えない)
    mixinというとC++ templateを想像するんですが、F#にこれを行わせることはできない(?)ので、結果として同じような事が出来るという意味でmixinと言っているのかも
    MIYAZAKI Shohei
    @hafuu
    英語の記事にmixinなんて言葉出てこないですー