Upgrade to Pro — share decks privately, control downloads, hide ads and more …

最強のスクリプト言語F#

adacola
September 28, 2020

 最強のスクリプト言語F#

F#5のバージョンアップでは主にF#のスクリプト言語としての機能が強化されました。
これはもう最強のスクリプト言語と言っても過言ではないのでは!?

adacola

September 28, 2020
Tweet

Other Decks in Programming

Transcript

  1. F# とは Microsoftが開発した .NET ⾔語のひとつ .NET Core や .NET Framework

    上で動作する OCamlの⽂法を パクった 参考にした ML 系⾔語の⼀種 オフサイドルール C#の舎弟 C#と同じNuGetをパッケージマネージャとして使う C#のライブラリはF#からも利⽤可能 C#⽤に作られたライブラリを美味しく使わせてもらうぜ︕ コンパイル⾔語だが、インタプリタ的な実⾏もできる 最強のスクリプト⾔語F# @adacola 2
  2. 関数型⾔語 F# 関数が第⼀級オブジェクト ⾼階関数 カリー化された関数 すべてが式 (型定義除く) 静的型付け 代数的データ型 強⼒な型推論

    (型注釈を書いたら負けだと思っている) 構造的部分型 (inline関数のみ) 型クラス…はありません︕︕ 最強のスクリプト⾔語F# @adacola 5
  3. F# のコード例 module Adacola.FSharp.Sample // 変数(イミュータブル) let hoge = "fuga"

    // 変数(ミュータブル) let mutable foo = "bar" foo <- "baz" // 関数。変数と同じような宣⾔になる。あとシャドーイングも試している let hoge x = let y = x + 1 y + 1 // 式の結果が戻り値 // リスト。各要素はセミコロン区切り、⾏末はセミコロン不要 let princesses = [ "キュアフローラ"; "キュアマーメイド" "キュアトゥインクル" "キュアスカーレット" ] // 配列。Range指定もできる let array = [| 1 .. 5 |] // 表⽰。あとString Interpolation printfn $"Goプリのプリキュアは {princesses} で %02d{List.length princesses} ⼈" 最強のスクリプト⾔語F# @adacola 6
  4. F# の特徴その1 パイプライン演算⼦ パイプライン演算⼦の⽣みの親はF# (UNIXのパイプラインの考え⽅を輸⼊) Fluent Interfaceが簡単に実現できる カリー化、部分適⽤とパイプライン演算⼦の相性は抜群 型推論にも⼀役買っている |>

    がパイプライン演算⼦、>> は関数合成 open FSharpPlus open FSharp.Data // 指定されたURLのページ内のハイパーリンクをすべて取得 let getAllLinks url = url |> Http.RequestString |> HtmlDocument.Parse |> HtmlDocument.descendantsNamed false ["a"] |> map (HtmlNode.attribute "href" >> HtmlAttribute.value) 最強のスクリプト⾔語F# @adacola 7
  5. F# の特徴その2 単位 乗除算は単位が合成され、単位が違う値の加減算はコンパイルエラー これでヤードポンド法も怖くない︕ コンパイル後は単位は消えインスタンス⽣成もないため実⾏速度に影響しない open FSharp.Data.UnitSystems.SI.UnitSymbols // SI単位系は標準で⽤意されている

    let length = 500.0<m> let time = 20.0<s> let velocity = length / time // 25.0<m/s> let square = length * length // 250000.0<m^2> let length' = sqrt square // 500.0<m> let mass = 60.0<kg> let accel = length / time / time // 1.25<m/s^2> let force: float<N> = mass * accel // 75.0<N> let error = length + time // コンパイルエラー // ⾃作単位を宣⾔することも可能 [<Measure>] type YEN 最強のスクリプト⾔語F# @adacola 8
  6. F# の特徴その3 コンピュテーション式 ⾔語内DSL モナド構⽂として使われることが多い let requestFirstLink url = async

    { let! response = url |> Http.AsyncRequestString let link = response |> getAllLinks |> head return! link |> Http.AsyncRequestString } open FSharpPlus let flattenLinks url = monad { let! link = url |> getAllLinks return! link |> getAllLinks } // FableだとJSのPromiseをF#で書ける promise { let! res = Fetch.fetch url [] let! txt = res.text() return txt.Length } 最強のスクリプト⾔語F# @adacola 9
  7. F# の特徴その4 Type Provider スキーマから静的に型定義を作る機能 JSONに対応する型定義をわざわざ書かなくてもよいし中間⽣成物も⽣まれない データベースのスキーマをインターネットで取得して静的にテーブルの型⽣成 swaggerから静的にWeb API クライアントを⽣成

    他のプログラム⾔語のバイナリを静的に読み込んで型定義付きラッパーを⽣成す るチートみたいなライブラリもある open System.IO open FSharpPlus open FSharp.Data type Recognition = JsonProvider<"""{"status":"success","candidates":[{"label":"hoge","score":0.8}]}"""> let tryRecognize imageFile = let image = imageFile |> File.ReadAllBytes let response = Http.RequestString(url, httpMethod = "POST", body = BinaryUpload image) let recognition = response |> Recognition.Parse if recognition.Status = "success" then recognition.Candidates |> map (fun candidate -> candidate.Label) |> Some else None 最強のスクリプト⾔語F# @adacola 10
  8. F# の特徴その5 代数的データ型 // 直積型 let a, b = 1,

    2 // タプル type Person = { // レコード Name: string Age: int } // 直和型、匿名レコード type Family = | Person of Person | Pet of {| Name: string; Master: Person |} let family = Pet {| Name = "マロ"; Master = { Name = "相⽥マナ"; Age = 14 } |} match family with | Person { Name = name } -> printfn $"⼈間で名前は{name}です" | Pet pet -> printfn $"ペットで名前は{pet.Name}、飼い主の名前は{pet.Master.Name}です" 最強のスクリプト⾔語F# @adacola 11
  9. F# のその他特徴 再帰関数、関数引数をいきなりパターンマッチ let rec fibonacci = function | 0

    -> 0 | 1 -> 1 | n -> fibonacci (n - 1) + fibonacci (n - 2) アクティブパターン Scalaのunapplyに相当 let (|Positive|_|) x = if x > 0 then Some x else None let (|Negative|_|) x = if x < 0 then x |> abs |> Some else None match -42 with | Positive result -> printfn $"positive abs:{result}" | Negative result -> printfn $"negative abs:{result}" | _ -> printfn "zero" 最強のスクリプト⾔語F# @adacola 12
  10. F# のその他特徴 nameof 変数名、関数名、モジュール名、名前空間名、型変数名などを⽂字列に変換できる type Hoge<'a> = Fuga of 'a

    let hoge = nameof Hoge // Hoge let fuga = nameof Fuga // Fuga let piyo x = nameof x // 何を与えても "x" が返る let hogeType<'a> (hoge: Hoge<'a>) = nameof<'a> // 何を与えても "a" が返る let x = 42 printfn $"{nameof x} の値は {x} です" match "fuga" with | nameof hoge -> printfn "hogeでした" | nameof fuga -> printfn "fugaでした" | other -> printfn $"その他の{other}でした" 最強のスクリプト⾔語F# @adacola 13
  11. 便利なライブラリ FSharpPlus 準標準ライブラリ。F#でモナモナしたいなら必須 FSharp.Data HTTPアクセス、HTMLパーザ、JSONやXMLやCSCのType Provider Argu 静的型付けコマンドラインパーザ FParsec パーザコンビネータ。正規表現では⼿に負えないパーズも任せろ︕

    Math.NET Numerics .NET⽤の数学ライブラリ。F#で便利に使えるヘルパー関数も⽤意されている R Type Provider Rを静的型付きで呼び出せるヤバいやつ 最強のスクリプト⾔語F# @adacola 14