å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®1.5
é£è¼ç®æ¬¡
- å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®1
- å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®1.5 â ä»å
- F#ã§ã®ãæ«å°¾ãã«ã¤ãã¦ã®è©±
- å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®2
- .NETã«ãããæ«å°¾æé©åã®æ¹æ³ã«ã¤ãã¦ã®è©±
- å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®2.5
- ç¶ç¶ã¢ããã¨ãF#ã®æ®å¿µãã®è©±
- å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®3
- ãã¹ã¦ãããããã¦å帰ãwhileã«æ¸ãç´ãæ¹æ³ã®è©±
ã¯ããã«
ååã¯ãCPSå¤æã«ãã£ã¦å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåé¿ããæ¹æ³ãç´¹ä»ãã¾ããã ãã®ä¸ã§ããæ«å°¾å¼ã³åºããã¨ããè¨èãåºã¦ãã¾ãããã詳細ã«ã¤ãã¦ã¯è§¦ãã¾ããã§ããã ãã®è¨äºã§ã¯ãæ¬é¡ããã¯ã¡ãã£ã¨èéã«é¸ãã¦ãF#ã«ããã¦ã¯ä½ããæ«å°¾ãã§ä½ãæé©åã®å¯¾è±¡ã¨ãªããå¼ã³åºãããªã®ãã説æãã¾ãã
åæç¥èã¨ãã¦ãä¸è¨è¨äºãç解ãã¦ãããã¨ã¨ãä¸é¨ã«ã¤ãã¦ã¯ILããªãã¨ãªãããããã¨ã§ãã 大é¨åã¯ILã«ã¤ãã¦ç¥ããªãã¦ãèªããã¯ãã§ãã
æ«å°¾
å帰é¢æ°ã®ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãåã話 ãã®1 ã§ã¯ãæ«å°¾ã®èª¬æã§ãã®ãããªããã°ã©ã ãæ±ãã
let example x = if f1 x then f2 x else 10 + f3 x
f1
, f2
, f3
ã®ãã¡ãf2
ã®ã¿ãæ«å°¾å¼ã³åºãããã¦ããã¨èª¬æãã¾ããã
ããã¯ééã£ã¦ã¯ãã¾ãããã F#ã§ãæ«å°¾ãã¨ã¿ãªãããä½ç½®ãã¿ãªãããªãä½ç½®ã¨ããã®ã¯èªæã§ã¯ããã¾ããã ããã§ãF#ã§ãæ«å°¾ãã¨ã¿ãªãããä½ç½®ãã¿ãªãããªãä½ç½®ã«ã¤ãã¦æãä¸ãã¦ã¿ã¦ããã¾ãã
ã¡ãªã¿ã«ãããã§èª¿ã¹ãçµæã¯ããã¾ã§ç¾å¨ã®å®è£ ã«ã¤ãã¦è¿°ã¹ããã®ã§ããã ä»æ§ã¨ãã¦æ«å°¾ãæ示ããã¦ããããã§ã¯ããã¾ããã®ã§ãå°æ¥å¤æ´ãããå¯è½æ§ã¯ããã¾ãã
調ã¹æ¹
F#ã®ä»æ§æ¸ã®
Expressionsã®ç« ã«åºã¦ããå¼ã«ã¤ãã¦ãé¢æ°ãå¼ã³åºããéã«tail.
ILãã¬ãã£ãã¯ã¹ãä»ããã©ããã調ã¹ã¾ãã
ã¡ãªã¿ã«ããã¯ãVS2013 / F#3.1.2ã§èª¿æ»ããçµæã§ãããéå»ãã¼ã¸ã§ã³ãå°æ¥ã®ãã¼ã¸ã§ã³ã§ã¯çµæãå¤ããå¯è½æ§ãããç¹ã«æ³¨æãã¦ãã ããã
(* ãããã®é¢æ°ãå®ç¾©ããã¦ããåæ *) let f x y = x + y let g x = f x 1 let h = g
F#ã§ã®æ«å°¾ä¸è¦§
blockã§å²ã¾ããå¼ã®æ«å°¾
let ``block`` () = (h 2)
blockã¯ã(
ã¨)
ã§å²ã¾ããå¼ã§ãå²ã¾ããä¸ã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
begin-endã§å²ã¾ããå¼ã®æ«å°¾
let ``begin-end`` () = begin h 2 end
begin-endã¯ãbegin
ã¨end
ã§å²ã¾ããå¼ã§ãå²ã¾ããä¸ã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
delayedã®lazy
ã«ç¶ãå¼ã®æ«å°¾
let ``delayed`` () = lazy (h 2)
delayedã¯lazy
ãã¼ã¯ã¼ãã§å§ã¾ãå¼ã§ãlazy
ã®å¾ãã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
functionã®æ¬ä½é¨åã®å¼ã®æ«å°¾
let ``function`` () = List.map (fun x -> h x)
functionã¯fun
ãã¼ã¯ã¼ãã§å§ã¾ãå¼ã§ãæ¬ä½é¨åã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
matching functionã®åæ¬ä½é¨åã®å¼ã®æ«å°¾
let ``matching function`` () = List.map (function 1 -> h 0 | x -> h x)
matching functionã¯function
ãã¼ã¯ã¼ãã§å§ã¾ãå¼ã§ãåæ¬ä½é¨åã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
sequential executionã®å¾ãå´ã®å¼ã®æ«å°¾
let ``sequential execution`` () = ignore (h 1); h2
sequential executionã¯;
ãããã¯æ¹è¡ã§åºåãããå¼ã®ä¸¦ã³ã§ãå¾ãå´ã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
matchã®ååå²ã®å¼ã®æ«å°¾
let ``match`` x = match x with 1 -> h 0 | x -> h x
matchã¯match
ãã¼ã¯ã¼ãã§å§ã¾ãå¼ã§ãååå²ã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
conditionalã®then
ã®å¼ã®æ«å°¾ã¨else
ã®å¼ã®æ«å°¾
let ``conditional`` cond = if cond then h 1 else h 2
conditionalã¯if
ãã¼ã¯ã¼ãã§å§ã¾ãå¼ã§ãthen
ã®å¼ã®æ«å°¾ã¨else
ã®å¼ã®æ«å°¾ã¯æ«å°¾ã§ãã
ãã ããelse
ã®ãªãconditionalã®å ´åã¯ãthen
ã®å¼ã®æ«å°¾ã ã¨ãã¦ãæ«å°¾ã«ã¯ãªããªãããã§ãã
[<MethodImpl(MethodImplOptions.NoInlining)>] let uf x = h x |> ignore let ``conditional 2`` cond = if cond then uf 1
ãã®é¢æ°ãæé©åãããæ«å°¾å¼ã³åºãã®çæããã§ãã«ãããã¨ã以ä¸ã®ãããªILãåããã¾ãã
IL_0000: nop IL_0001: ldarg.0 IL_0002: brfalse.s IL_000c IL_0004: ldc.i4.1 IL_0005: call void Sample::uf(int32) IL_000a: nop IL_000b: ret IL_000c: ret
tail.
ãä»ãã¦ãã¾ããã
æ«å°¾ã£ã½ããæ«å°¾ã§ã¯ãªããã®
assignment
let ``assignment`` () = let mutable x = 1 x <- h 2
å½ç¶ã¨è¨ãã°å½ç¶ã§ãããh 2
ã®çµæãx
ã«ä»£å
¥ããå¿
è¦ããããããæ«å°¾ã§ã¯ããã¾ããã
tuple
let ``tuple`` () = (h 1, h 2)
System.Tuple
ã®ã³ã³ã¹ãã©ã¯ã¿å¼ã³åºããé ãã¦ãããããæ«å°¾ã§ã¯ããã¾ããã
ãã®ããã«æ¸ãæããã¨ããããããã§ãããã
let ``tuple`` () = System.Tuple.Create(h 1, h 2)
try/with
let ``try/with`` () = try h 1 with _ -> h 2
ä¾å¤å¦çãããã¯ãæããããã«ã¯ILã¬ãã«ã§ã¯leave
ãå¿
è¦ãªããã
try
ãwith
ã®ä¸ã®å¼ã¯æ«å°¾ã§ã¯ããã¾ããã
try/finally
[<MethodImpl(MethodImplOptions.NoInlining)>] let uf x = h x |> ignore let ``try/finally`` () = try h 1 finally uf 2
finally
ãããã¯ãæããããã«ã¯ILã¬ãã«ã§ã¯endfinally
ãå¿
è¦ãªããã
finally
ã®ä¸ã®å¼ã¯æ«å°¾ã§ã¯ããã¾ããã
determinstic disposal
let ``determinstic disposal`` () = use x = { new IDisposable with member __.Dispose() = () } h 2
use
ã¯try/finaly
ãé ãã¦ãã¾ãã®ã§ããããæ«å°¾ã§ã¯ããã¾ããã
ä¾ãã°ä¸ã®ã³ã¼ãã¯ã以ä¸ã®ãããªã³ã¼ãã«æ¸ãæãå¯è½ã§ãã
let ``determinstic disposal`` () = let x = { new IDisposable with member __.Dispose() = () } let mutable result = 0 try result <- h 2 finally if x != null then x.Dispose() result
æé©åãããå¼ã³åºãã¨ãããªãå¼ã³åºã
ããã¾ã§ã§ãæ«å°¾ãã¯åããã¾ããã ã§ã¯ãF#ã«ããã¦ãæ«å°¾å¼ã³åºãæé©åã®å¯¾è±¡ã¨ãªããå¼ã³åºããããã¡ãã¨ç解ãã¦ããã¨è¨ããã§ããããï¼
ããã§ã¯ãF#ã«ããããæ«å°¾å¼ã³åºãæé©åã«ãã£ã¦æé©åãããå¼ã³åºããã«ã¤ãã¦æãä¸ãã¦ã¿ã¦ããã¾ãã
ããã§èª¿ã¹ãçµæãããã¾ã§ç¾å¨ã®å®è£ ã«ã¤ãã¦è¿°ã¹ããã®ã§ããã ä»æ§ã¨ãã¦æé©åãããå¼ã³åºããæ示ããã¦ããããã§ã¯ããã¾ããã®ã§ãå°æ¥å¤æ´ãããå¯è½æ§ã¯ããã¾ãã
æé©åãããå¼ã³åºã
é¢æ°å¼ã³åºã
f x
é¢æ°å¼ã³åºããæ«å°¾ã®ä½ç½®ã«ããå ´åããã®å¼ã³åºãã¯æé©åããã¾ãã ãããæé©åãããªãã£ããå°ãã¾ãããã
ã¡ã½ããå¼ã³åºã
x.M(y)
ã¡ã½ããå¼ã³åºããæ«å°¾ã®ä½ç½®ã«ããå ´åããã®å¼ã³åºãã¯æé©åããã¾ãã F#ã§ã®é¢æ°ã¯ã¡ã½ããã¨ãã¦å®è£ ããã¦ããã®ã§ãé¢æ°å¼ã³åºããæé©åãããã®ã§ããã°ãã¡ããæé©åãããªãçç±ã¯ãªãã§ãããã
é¢æ°å¤ã®èµ·å
let g = f g x
é¢æ°ãç´æ¥å¼ã³åºããã(é¨åé©ç¨ãªã©ãè¡ã£ã¦)å¤ã¨ãã¦æ±ãå ´åã
å
é¨ã§ã¯FSharpFunc<'T, 'U>
åã¨ãã¦è¡¨ç¾ããã¾ã*1ã
ãã®ãããªå ´åã§ããæ«å°¾ã®ä½ç½®ã§é¢æ°å¤ãèµ·åãã¦ããå ´åããã®å¼ã³åºãã¯æé©åããã¾ãã å®å¿ãã¦é¨åé©ç¨ã§ãã¾ããã
æ¼ç®å
x + y
æ¼ç®åãã¦ã¼ã¶å®ç¾©ãã¦ããå ´åãããã¯é¢æ°ãã¡ã½ããã§å®è£ ãããã¨ã«ãªãããã æ«å°¾ã®ä½ç½®ã§æ¼ç®åãé©ç¨ãã¦ããå ´åã¯ãã®å¼ã³åºãã¯æé©åããã¾ãã
æé©åãããªãå¼ã³åºã
ã³ã³ã¹ãã©ã¯ã¿å¼ã³åºã
C(x)
ã³ã³ã¹ãã©ã¯ã¿ã®å¼ã³åºããæ«å°¾ã®ä½ç½®ã«ãã£ã¦ãããã®å¼ã³åºãã¯æé©åããã¾ããã
ã³ã³ã¹ãã©ã¯ã¿ã®å¼ã³åºãã¯newobj
ã¨ããILãçºè¡ãããã®ã§ããããã®ILã«å¯¾ãã¦tail.
ãã¬ãã£ãã¯ã¹ã¯ä»ãããªãã®ã§ãã
ãã®ãããã³ã³ã¹ãã©ã¯ã¿ã®å¼ã³åºãã絡ãã¨å¿
ãã¹ã¿ãã¯ãæ¶è²»ããããã¨ã«ãªãã¾ãã
F#ã§ã¯ã³ã³ã¹ãã©ã¯ã¿ã®å¼ã³åºããããããã¨ãåããã«ããé¨åãå¹¾ã¤ãããã®ã§ãããã¯ç½ ã«ãªãå ´åãããã¾ãã
ã³ã³ã¹ãã©ã¯ã¿å ã§ã®ã³ã³ã¹ãã©ã¯ã¿å¼ã³åºã
type C (res: int) = new (acc: int, n: int) = if n = 0 then C(acc) else C(acc * n, n - 1) member __.Result = res
ã³ã³ã¹ãã©ã¯ã¿å
ã§ä»ã®(èªåãããã¯è¦ªã®)ã³ã³ã¹ãã©ã¯ã¿ãå¼ã³åºãå ´åãnewobj
ã§ã¯ãªãcallvirt
ãªã©ã®callç³»ã®ILãçºè¡ããã¾ãã
ãããããããtail.
ãã¬ãã£ãã¯ã¹ã¯ä»ããªãããã§ãã
ILçã«ã¯ããã«tail.
ãã¬ãã£ãã¯ã¹ãä»ãã¦ãåé¡ãªããããªã®ã§ããããããã¨å°æ¥ãã®æåã¯å¤ããããããã¾ãã(ããå¤ãããªãããããã¾ãã)ã
*1:ãã®ãããªé¢æ°å¤ã®ãã¼ã«ãããã表示ãããã¨ãæ¬å¼§ã§å²ã¾ãã¦ãã¾ã