F#

   bleis-tift


August 28, 2011
F#
      F#
NParsec    FParsec
F#
F#




OCaml

.NET Framework
F#
F#
cons
1 3
[1; 2; 3]
[1..3]
1::2::3::[]
1::2::[3]
[ 1
  2
  3 ]
cons
cons
cons
cons
cons
cons
let xs = [2..10]
let ys = 1::xs
int   string   int * string
1
let x, y = 10, 20
printfn "%A" (x, y) // => (10, 20)

             2
let (x,   y) as tpl = 1,   2
printfn   "%A" tpl         // => (1, 2)
printfn   "%A" (x, y)      // => (1, 2)
printfn   "(%d, %d)" x y   // => (1, 2)
let [x;   y] as lst = [1; 2]
printfn   "%A" lst       // => [1; 2]
printfn   "%A" [x; y]    // => [1; 2]
printfn   "[%d; %d]" x y // => [1; 2]


warning FS0025:
            ’[_;_;_]’
1
1
1
2



(2, "hoge") // int * string


//
[2; "hoge"]

[box 1; box "hoge"] // obj list
2
//     ,
let p = "       ", 21


type Person = {
  Name: string
  Age: int
}
let p = { Name = "       "; Age = 21 }

                     4
F#


type Person(name: string, age: int) =
  member this.Name = name
  member this.Age = age
let p = Person("        ", 21)


type Person = { Name: string; Age: int }
let p = { Name = "       "; Age = 21 }
type Person(name: string, age: int) =
  member x.Name = name
  member x.Age = age
let f p = p.Name


error FS0072:
type Person = { Name: string; Age: int }
let f p = p.Name


type Person =
  {Name: string;
   Age: int;}
val f : Person -> string
(   )
(enum)
HtmlElem
C#


public abstract class HtmlElem {}
public class Heading : HtmlElem {
  public int Level { get; private set; }
  public string Text { get; private set; }
  public Heading(int level, string txt) {
    Level = level; Text = txt; } }
public class Text : HtmlElem {
  public string Text { get; private set; }
  public Text(string txt) {
    Text = txt; } }
public class HorizontalLine : HtmlElem {}
F#




type HtmlElem =
| Text of string
| Heading of int * string
| HorizontalLine
Equals

GetHashCode
Make static analyzers happy
==           !=




ToString
sprintf ”%A”
F#




F#
     C#
HtmlElem HTML
type HtmlElem =
| Heading of int * string
| Text of string
| HorizontalLine

let toHtmlStr elem =
  let h lv s =
    sprintf "<h%d>%s</h%d>" lv s lv
  match elem with
  | Heading(level, txt) -> h level txt
  | Text txt -> "<p>" + txt + "</p>"
  | HorizontalLine -> "<hr/>"
                    match
let add =   function
| 0, y ->   y
| x, 0 ->   x
| x, y ->   x + y
                       function
match     function


match
let add tpl =
  match tpl with
  | x, y -> x + y

function
let add = function
| x, y -> x + y
type t = { Tag: int; Value: int }
let value { Value = v } = v
match

match
let add tpl =
  match tpl with
  | x, y -> x + y

function
let add = function
| x, y -> x + y


let add (x, y) = x + y
Person
type Name = {
  FirstName: string
  LastName: string
}
type Person = { Name: Name; Age: int }

let f x =
  let { Name = { FirstName = fn } } = x
  fn
F#
Maybe
type MaybeBuilder() =
  member this.Bind(x, f) =
    x |> Option.bind f
  member this.Return(x) = Some x
let maybe = MaybeBuilder()

let plus   db = maybe {
  let! x   = db |> Map.tryFind "x"
  let! y   = db |> Map.tryFind "y"
  return   x + y
}
Map-Reduce   ( )




fold    reduce
fold
fold   reduce




fold   reduce
F#

fold reduce
> List.fold;;
val it : ((’a -> ’b -> ’a) -> ’a -> ’b list -> ’a)
 = <fun:clo@1>
> List.reduce;;
val it : ((’a -> ’a -> ’a) -> ’a list -> ’a)
 = <fun:clo@2-1>


fold

reduce                   list
                  list
fold
fold
fold
fold
fold



fold
sum
forall
map
filter
fold



fold
sum
forall
map
filter
fold    sum




sum
let sum xs =
  List.fold (+) 0 xs
fold     forall



forall
let forall p xs =
   xs
   |> List.fold (fun acc x -> acc && (p x)) true



exists
fold   map


map
let map f xs =
  ([], xs)
  ||> List.fold (fun acc x ->
        acc @ [f x]
      )
fold   filter


filter
let filter p xs =
  ([], xs)
  ||> List.fold begin acc x ->
        if p x then acc @ [x]
        else acc
      end
fold


fold

       fold(   unfold)
                         fold
F#
F#
F#
     .NET
F#



        F#
.NET Framework
.NET Framework



                       2.0
             .NET Framework


                  F#
.NET Framework


   F# .NET Framework2.0
   Runtime
   .NET Framework2.0   LINQ
       F #   List



.NET Framework           2.0   F#
.NET Framework

                  4.0                 F#
       TDDBC Tokyo 1.6

              C#        (         )
           KeyValueTime.cs       42
           SystemClock.cs        30
           TddbcKeyValueStore.cs 67

             F#       (          )
             KeyValueStore.fs 48

C#   139             F#   48
.NET Framework

                   4.0                 F#
        TDDBC Tokyo 1.6

           C#        (            )
     KeyValueTimeTest.cs       141
     SystemClockTest.cs        34
     TddbcKeyValueStoreTest.cs 346      ( )

           F#        (             )
            KeyValueStore.fs 170

C#   521           F#     170
.NET Framework




.NET Framework        F#

           2.0   C#
      F#
F#

.NET        F#

   option
F#   C#
VB
.NET



C#   VB
F#   list    F#     dll



            array   seq
static

NewHoge
                        Tag
                          IsHoge



          F#
module Hoge
let plus10 = ((+)10)
       Hoge.plus10
        FSharp.Core.FSharpFunc
                       FSharp.Core.dll
NParsec   FParsec
yacc       lex
       yacc lex
BNF
parsec
JParsec
NParsec
FParsec
scala.util.parsing
Boost.Spirit
NParsec



parsec    .NET
C#
                           C#

          Java
Scanner
FParsec




parsec   .NET
F#
NParsec   FParsec
NParsec


var lazyexpr = new Parser<double>[1];
var plazyexpr = Parsers.Lazy<double>(() =>
  lazyexpr[0]
);
var pterm =
  plazyexpr.Between(popen, pclose) | pnum;
var pexpr = ...
lazyexpr[0] = pexpr;
FParsec


let pexpr, exprref =
  createParserForwardedToRef()
let pterm =
      pexpr |> between popen pclose
  <|> pnum
do exprref := ...
F#   10   C#    54

     C#
           Visitor
C#
F#
NParsec         Bind
return Parsers.Return(...)
FParsec
NParsec
F#



     FParsec

               F#

仕事で使うF#

  • 1.
    F# bleis-tift August 28, 2011
  • 3.
    F# F# NParsec FParsec
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
    1 3 [1; 2;3] [1..3] 1::2::3::[] 1::2::[3] [ 1 2 3 ]
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
    let xs =[2..10] let ys = 1::xs
  • 16.
    int string int * string
  • 22.
    1 let x, y= 10, 20 printfn "%A" (x, y) // => (10, 20) 2 let (x, y) as tpl = 1, 2 printfn "%A" tpl // => (1, 2) printfn "%A" (x, y) // => (1, 2) printfn "(%d, %d)" x y // => (1, 2)
  • 23.
    let [x; y] as lst = [1; 2] printfn "%A" lst // => [1; 2] printfn "%A" [x; y] // => [1; 2] printfn "[%d; %d]" x y // => [1; 2] warning FS0025: ’[_;_;_]’
  • 24.
  • 25.
  • 26.
  • 27.
    2 (2, "hoge") //int * string // [2; "hoge"] [box 1; box "hoge"] // obj list
  • 28.
  • 31.
    // , let p = " ", 21 type Person = { Name: string Age: int } let p = { Name = " "; Age = 21 } 4
  • 32.
    F# type Person(name: string,age: int) = member this.Name = name member this.Age = age let p = Person(" ", 21) type Person = { Name: string; Age: int } let p = { Name = " "; Age = 21 }
  • 33.
    type Person(name: string,age: int) = member x.Name = name member x.Age = age let f p = p.Name error FS0072:
  • 34.
    type Person ={ Name: string; Age: int } let f p = p.Name type Person = {Name: string; Age: int;} val f : Person -> string
  • 35.
    ( )
  • 36.
  • 37.
  • 38.
    C# public abstract classHtmlElem {} public class Heading : HtmlElem { public int Level { get; private set; } public string Text { get; private set; } public Heading(int level, string txt) { Level = level; Text = txt; } } public class Text : HtmlElem { public string Text { get; private set; } public Text(string txt) { Text = txt; } } public class HorizontalLine : HtmlElem {}
  • 39.
    F# type HtmlElem = |Text of string | Heading of int * string | HorizontalLine
  • 40.
  • 41.
  • 42.
  • 44.
    HtmlElem HTML type HtmlElem= | Heading of int * string | Text of string | HorizontalLine let toHtmlStr elem = let h lv s = sprintf "<h%d>%s</h%d>" lv s lv match elem with | Heading(level, txt) -> h level txt | Text txt -> "<p>" + txt + "</p>" | HorizontalLine -> "<hr/>" match
  • 45.
    let add = function | 0, y -> y | x, 0 -> x | x, y -> x + y function
  • 46.
    match function match let add tpl = match tpl with | x, y -> x + y function let add = function | x, y -> x + y
  • 47.
    type t ={ Tag: int; Value: int } let value { Value = v } = v
  • 48.
    match match let add tpl= match tpl with | x, y -> x + y function let add = function | x, y -> x + y let add (x, y) = x + y
  • 49.
    Person type Name ={ FirstName: string LastName: string } type Person = { Name: Name; Age: int } let f x = let { Name = { FirstName = fn } } = x fn
  • 50.
  • 51.
    Maybe type MaybeBuilder() = member this.Bind(x, f) = x |> Option.bind f member this.Return(x) = Some x let maybe = MaybeBuilder() let plus db = maybe { let! x = db |> Map.tryFind "x" let! y = db |> Map.tryFind "y" return x + y }
  • 53.
    Map-Reduce ( ) fold reduce fold
  • 54.
    fold reduce fold reduce
  • 55.
    F# fold reduce > List.fold;; valit : ((’a -> ’b -> ’a) -> ’a -> ’b list -> ’a) = <fun:clo@1> > List.reduce;; val it : ((’a -> ’a -> ’a) -> ’a list -> ’a) = <fun:clo@2-1> fold reduce list list
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
    fold sum sum let sum xs = List.fold (+) 0 xs
  • 63.
    fold forall forall let forall p xs = xs |> List.fold (fun acc x -> acc && (p x)) true exists
  • 64.
    fold map map let map f xs = ([], xs) ||> List.fold (fun acc x -> acc @ [f x] )
  • 65.
    fold filter filter let filter p xs = ([], xs) ||> List.fold begin acc x -> if p x then acc @ [x] else acc end
  • 66.
    fold fold fold( unfold) fold
  • 67.
  • 68.
    F# F# .NET
  • 69.
    F# F# .NET Framework
  • 70.
    .NET Framework 2.0 .NET Framework F#
  • 71.
    .NET Framework F# .NET Framework2.0 Runtime .NET Framework2.0 LINQ F # List .NET Framework 2.0 F#
  • 72.
    .NET Framework 4.0 F# TDDBC Tokyo 1.6 C# ( ) KeyValueTime.cs 42 SystemClock.cs 30 TddbcKeyValueStore.cs 67 F# ( ) KeyValueStore.fs 48 C# 139 F# 48
  • 73.
    .NET Framework 4.0 F# TDDBC Tokyo 1.6 C# ( ) KeyValueTimeTest.cs 141 SystemClockTest.cs 34 TddbcKeyValueStoreTest.cs 346 ( ) F# ( ) KeyValueStore.fs 170 C# 521 F# 170
  • 74.
  • 75.
    F# .NET F# option
  • 76.
    F# C# VB
  • 77.
  • 78.
    F# list F# dll array seq
  • 79.
    static NewHoge Tag IsHoge F#
  • 80.
    module Hoge let plus10= ((+)10) Hoge.plus10 FSharp.Core.FSharpFunc FSharp.Core.dll
  • 81.
    NParsec FParsec
  • 83.
    yacc lex yacc lex
  • 84.
  • 85.
  • 86.
    NParsec parsec .NET C# C# Java Scanner
  • 87.
  • 88.
    NParsec FParsec
  • 89.
    NParsec var lazyexpr =new Parser<double>[1]; var plazyexpr = Parsers.Lazy<double>(() => lazyexpr[0] ); var pterm = plazyexpr.Between(popen, pclose) | pnum; var pexpr = ... lazyexpr[0] = pexpr;
  • 90.
    FParsec let pexpr, exprref= createParserForwardedToRef() let pterm = pexpr |> between popen pclose <|> pnum do exprref := ...
  • 91.
    F# 10 C# 54 C# Visitor
  • 92.
  • 93.
    NParsec Bind return Parsers.Return(...) FParsec
  • 94.
  • 98.
    F# FParsec F#