Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®èšäºã§ã¯ããã©ã¡ãŒã¿ãŒãå®çŸ©ãã颿°ãã¡ãœãããããã³ããããã£ã«åŒæ°ãæž¡ãããã®èšèªãµããŒãã«ã€ããŠèª¬æããŸãã ããã«ã¯ãåç §æž¡ãã®æ¹æ³ãšãå¯å€æ°ã®åŒæ°ãåãåãããšãã§ããã¡ãœãããå®çŸ©ããŠäœ¿çšããæ¹æ³ã«é¢ããæ å ±ãå«ãŸããŠããŸãã
"ãã©ã¡ãŒã¿ãŒ" ãšããçšèªã¯ãæå®ãããããšãæ³å®ãããå€ã®ååã説æããããã«äœ¿çšãããŸãã "åŒæ°" ãšããçšèªã¯ãåãã©ã¡ãŒã¿ãŒã«æå®ãããå€ã«äœ¿çšãããŸãã
ãã©ã¡ãŒã¿ãŒã¯ãã¿ãã«ãŸãã¯ã«ãªãŒå圢åŒããŸãã¯ãã® 2 ã€ã®çµã¿åããã§æå®ã§ããŸãã åŒæ°ã¯ãæç€ºçãªãã©ã¡ãŒã¿ãŒåã䜿çšããŠæž¡ãããšãã§ããŸãã ã¡ãœããã®ãã©ã¡ãŒã¿ãŒãçç¥å¯èœãšããŠæå®ããŠãæ¢å®å€ãä»äžããããšãã§ããŸãã
ãã©ã¡ãŒã¿ãŒ ãã¿ãŒã³
颿°ããã³ã¡ãœããã«æž¡ããã©ã¡ãŒã¿ãŒã¯ãéåžžã¯ã¹ããŒã¹ã§åºåããããã¿ãŒã³ã§ãã ã€ãŸããååãšããŠã颿°ãŸãã¯ã¡ã³ããŒã®ãã©ã¡ãŒã¿ãŒ ãªã¹ãã§ã¯ããmatch åŒãã§èª¬æãããŠãããã¿ãŒã³ã®ããããã䜿çšã§ããŸãã
éåžžãã¡ãœããã§ã¯åŒæ°ãæž¡ãããã«ã¿ãã«åœ¢åŒã䜿çšãããŸãã ããã«ããã.NET ã¡ãœããã§åŒæ°ãæž¡ãããæ¹æ³ãšã¿ãã«åœ¢åŒãäžèŽãããããä»ã® .NET èšèªã®èгç¹ããçµæãããæç¢ºã«ãªããŸãã
ã«ãªãŒå圢åŒã¯ãlet ãã€ã³ãã£ã³ã°ã䜿çšããŠäœæããã颿°ã§æããã䜿çšãããŸãã
æ¬¡ã®æ¬äŒŒã³ãŒãã¯ãã¿ãã«ãšã«ãªãŒååŒæ°ã®äŸã瀺ããŠããŸãã
// Tuple form.
member this.SomeMethod(param1, param2) = ...
// Curried form.
let function1 param1 param2 = ...
äžéšã®åŒæ°ãã¿ãã«ã«ãããäžéšããªãå Žåã¯ãçµåããã圢åŒã䜿çšã§ããŸãã
let function2 param1 (param2a, param2b) param3 = ...
ãã©ã¡ãŒã¿ãŒ ãªã¹ãã§ã¯ä»ã®ãã¿ãŒã³ã䜿çšããããšãã§ããŸããããã©ã¡ãŒã¿ãŒ ãã¿ãŒã³ããã¹ãŠã®å¯èœãªå
¥åãšäžèŽããªãå Žåã¯ãå®è¡æã«äžå®å
šãªäžèŽãçºçããå¯èœæ§ããããŸãã äŸå€ MatchFailureException ã¯ãåŒæ°ã®å€ããã©ã¡ãŒã¿ãŒ ãªã¹ãã§æå®ããããã¿ãŒã³ãšäžèŽããªãå Žåã«çæãããŸãã ãã©ã¡ãŒã¿ãŒ ãã¿ãŒã³ã§äžå®å
šãªäžèŽã蚱容ãããŠããå Žåã¯ãã³ã³ãã€ã©ã«ãã£ãŠèŠåãçºè¡ãããŸãã éåžžããã©ã¡ãŒã¿ãŒ ãªã¹ãã«åœ¹ç«ã€ãã¿ãŒã³ãå°ãªããšãä»ã« 1 ã€ãããŸããããã¯ã¯ã€ã«ãã«ãŒã ãã¿ãŒã³ã§ãã æå®ãããåŒæ°ãåã«ç¡èŠããå Žåã¯ããã©ã¡ãŒã¿ãŒ ãªã¹ãå
ã§ã¯ã€ã«ãã«ãŒã ãã¿ãŒã³ã䜿çšããŸãã æ¬¡ã®ã³ãŒãã¯ãåŒæ°ãªã¹ãå
ã§ã®ã¯ã€ã«ãã«ãŒã ãã¿ãŒã³ã®äœ¿çšã瀺ããŠããŸãã
let makeList _ = [ for i in 1 .. 100 -> i * i ]
// The arguments 100 and 200 are ignored.
let list1 = makeList 100
let list2 = makeList 200
ã¯ã€ã«ãã«ãŒã ãã¿ãŒã³ã¯ã次ã®ã³ãŒãã®ããã«ãéåžžã¯æååé åãšããŠæå®ãããã³ãã³ã ã©ã€ã³åŒæ°ã«é¢å¿ããªããããã°ã©ã ãžã®ã¡ã€ã³ ãšã³ã㪠ãã€ã³ããªã©ã§æž¡ãããåŒæ°ãäžèŠãªå Žåã«äŸ¿å©ã§ãã
[<EntryPoint>]
let main _ =
printfn "Entry point!"
0
åŒæ°å
ã§äœ¿çšãããããšã®ãããã®ä»ã®ãã¿ãŒã³ãšããŠã¯ãas ãã¿ãŒã³ãããã³å€å¥å
±çšäœãšã¢ã¯ãã£ã ãã¿ãŒã³ã«é¢é£ä»ããããèå¥åãã¿ãŒã³ããããŸãã æ¬¡ã®ããã«ãåäžã±ãŒã¹ã®å€å¥å
±çšäœãã¿ãŒã³ã䜿çšã§ããŸãã
type Slice = Slice of int * int * string
let GetSubstring1 (Slice(p0, p1, text)) =
printfn "Data begins at %d and ends at %d in string %s" p0 p1 text
text[p0..p1]
let substring = GetSubstring1 (Slice(0, 4, "Et tu, Brute?"))
printfn "Substring: %s" substring
åºåã¯æ¬¡ã®ãšããã§ãã
Data begins at 0 and ends at 4 in string Et tu, Brute?
Et tu
ã¢ã¯ãã£ã ãã¿ãŒã³ã¯ã次ã®äŸã®ããã«ãåŒæ°ãç®çã®åœ¢åŒã«å€æãããšããªã©ã«ããã©ã¡ãŒã¿ãŒãšããŠåœ¹ç«ã¡ãŸãã
type Point = { x : float; y : float }
let (| Polar |) { x = x; y = y} =
( sqrt (x*x + y*y), System.Math.Atan (y/ x) )
let radius (Polar(r, _)) = r
let angle (Polar(_, theta)) = theta
次ã®ã³ãŒãè¡ã«ç€ºãããã«ãas ãã¿ãŒã³ã䜿çšããŠãäžèŽããå€ãããŒã«ã«å€ãšããŠæ ŒçŽããããšãã§ããŸãã
let GetSubstring2 (Slice(p0, p1, text) as s) = s
å Žåã«ãã䜿çšããããã 1 ã€ã®ãã¿ãŒã³ã¯ãæé»çãªåŒæ°ã«å¯ŸããŠãã¿ãŒã³ ããããçŽã¡ã«å®è¡ããã©ã ãåŒã颿°ã®æ¬äœãšããŠæå®ããããšã«ãããæåŸã®åŒæ°ãç¡åã®ãŸãŸã«ãã颿°ã§ãã ãã®äŸã次ã«ã³ãŒãè¡ã§ç€ºããŸãã
let isNil = function [] -> true | _::_ -> false
ãã®ã³ãŒãã«ãã£ãŠããžã§ããªã㯠ãªã¹ããåãåã£ãŠããªã¹ãã空ã®å Žåã«ã¯ true ãããã以å€ã®å Žåã«ã¯ false ãè¿ã颿°ãå®çŸ©ãããŸãã ãã®ãããªææ³ã䜿çšãããšãã³ãŒããèªã¿ã«ãããªããããããããŸãã
å Žåã«ãã£ãŠã¯ãäžå®å šãªäžèŽãå«ããã¿ãŒã³ã圹ã«ç«ã€ããšããããŸããããšãã°ãããã°ã©ã å ã®ãªã¹ãã«èŠçŽ ã 3 ã€ãããªãããšãããã£ãŠããå Žåã¯ããã©ã¡ãŒã¿ãŒ ãªã¹ãã§æ¬¡ã®ãããªãã¿ãŒã³ã䜿çšã§ããŸãã
let sum [a; b; c;] = a + b + c
äžå®å šãªäžèŽããããã¿ãŒã³ã®äœ¿çšã¯ãã¯ã€ã㯠ãããã¿ã€ãã³ã°ããã®ä»ã®äžæçãªçšéã«æé©ã§ãã ã³ã³ãã€ã©ã«ããããã®ãããªã³ãŒãã«å¯ŸããŠèŠåãçºè¡ãããŸãã ãã®ãããªãã¿ãŒã³ã¯ãå¯èœãªãã¹ãŠã®å ¥åã®äžè¬çãªã±ãŒã¹ã«å¯Ÿå¿ã§ããªããããã³ã³ããŒãã³ã API ã«ã¯é©ããŠããŸããã
ååä»ãåŒæ°
ã¡ãœããã®åŒæ°ã¯ãã³ã³ãã§åºåãããåŒæ°ãªã¹ãå ã®äœçœ®ã«ãã£ãŠæå®ã§ããŸãããŸãã¯ãååãçå·ãæž¡ãå€ã®é ã«æå®ããŠã¡ãœããã«æç€ºçã«æž¡ãããšãã§ããŸãã ååã䜿çšããŠæå®ããå Žåã¯ã宣èšã§äœ¿çšãããŠãããã®ãšã¯ç°ãªãé åºã§åºçŸããããšããããŸãã
ååä»ãåŒæ°ã䜿çšãããšãã³ãŒããèªã¿ããããªããã¡ãœãã ãã©ã¡ãŒã¿ãŒã®äžŠã¹æ¿ããªã©ãAPI ã®ç¹å®ã®çš®é¡ã®å€æŽãžã®é©å¿æ§ãé«ãŸããŸãã
ååä»ãåŒæ°ã¯ãlet ã§ãã€ã³ãããã颿°ã颿°å€ããŸãã¯ã©ã ãåŒã§ã¯ãªããã¡ãœããã«å¯ŸããŠã®ã¿äœ¿çšã§ããŸãã
ååä»ãåŒæ°ã®äœ¿ç𿹿³ã次ã®ã³ãŒãäŸã«ç€ºããŸãã
type SpeedingTicket() =
member this.GetMPHOver(speed: int, limit: int) = speed - limit
let CalculateFine (ticket : SpeedingTicket) =
let delta = ticket.GetMPHOver(limit = 55, speed = 70)
if delta < 20 then 50.0 else 100.0
let ticket1 : SpeedingTicket = SpeedingTicket()
printfn "%f" (CalculateFine ticket1)
ã¯ã©ã¹ ã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒã³åºãã§ã¯ãååä»ãåŒæ°ãšåæ§ã®æ§æã䜿çšããŠãã¯ã©ã¹ã®ããããã£å€ãèšå®ã§ããŸãã æ¬¡ã«ããã®æ§æã®äŸã瀺ããŸãã
type Account() =
let mutable balance = 0.0
let mutable number = 0
let mutable firstName = ""
let mutable lastName = ""
member this.AccountNumber
with get() = number
and set(value) = number <- value
member this.FirstName
with get() = firstName
and set(value) = firstName <- value
member this.LastName
with get() = lastName
and set(value) = lastName <- value
member this.Balance
with get() = balance
and set(value) = balance <- value
member this.Deposit(amount: float) = this.Balance <- this.Balance + amount
member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount
let account1 = new Account(AccountNumber=8782108,
FirstName="Darren", LastName="Parker",
Balance=1543.33)
詳现ã«ã€ããŠã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒ (F#) ã«é¢ããèšäºãåç §ããŠãã ããã
ãããã㣠ã»ãã¿ãŒãåŒã³åºãã®ãšåãææ³ãããªããžã§ã¯ããè¿ãã¡ãœãã (ãã¡ã¯ã㪠ã¡ãœãããªã©) ã«ãé©çšãããŸãã
type Widget() =
member val Width = 1 with get,set
member val Height = 1 with get,set
type WidgetFactory =
static member MakeNewWidget() =
new Widget()
static member AdjustWidget(w: Widget) =
w
let w = WidgetFactory.MakeNewWidget(Width=10)
w.Width // = 10
w.Height // = 1
WidgetFactory.AdjustWidget(w, Height=10)
w.Height // = 10
ãããã®ã¡ã³ããŒã¯ã©ã®ãããªåŠçã§ãå®è¡ã§ããæ§æã¯å®è³ªçã«ãæçµçãªå€ãè¿ãåã«ãããã㣠ã»ãã¿ãŒãåŒã³åºãããã®ç瞮圢ã§ããããšã«æ³šæããŠãã ããã
ååä»ãåŒæ°ãå¿ èŠ
çæããããã©ã¡ãŒã¿ãŒé åºã®å€æŽããåŒã³åºããä¿è·ããã«ã¯ã System.Diagnostics.CodeAnalysis.RequireNamedArgumentsAttributeã䜿çšããŸãã
Note
ãã㯠F# 11.2 æ©èœã§ãã .NET 11.0.100 SDK ã§ã<LangVersion>preview</LangVersion>ãæå¹ã«ããŸãã 屿§ã¯ãåç
§å
ã®ã¡ã¿ããŒã¿ãŸãã¯ãœãŒã¹ã«ååšããå¿
èŠããããŸããã³ã³ãã€ã©ã¯ãããåæããŸããã
open System.Diagnostics.CodeAnalysis
type Query =
[<RequireNamedArguments>]
static member Execute(numerator: decimal, denominator: decimal) =
numerator / denominator
let ratio = Query.Execute(numerator = 3m, denominator = 4m)
// 0.75M; Query.Execute(3m, 4m) is rejected.
Query.Execute(3m, 4m) ã¯æåŠãããŸãã 宣èšã®é åºã倿Žãããšãååä»ãåŒã³åºãã®æå³ãä¿æãããŸãããã©ã¡ãŒã¿ãŒã®ååã倿Žãããšããã©ã¡ãŒã¿ãŒãäžæãããŸãã
ãã®èŠåã¯ãããããã£ãã€ã³ãã¯ãµãŒãããªã²ãŒãåŒã³åºãããŸãã¯ã¢ãžã¥ãŒã«é¢æ°ã§ã¯ãªããã¡ãœãããšã³ã³ã¹ãã©ã¯ã¿ãŒã察象ãšããŠããŸãã çç¥å¯èœãªåŒæ°ã¯çç¥ã§ããŸããå±éãããäœçœ®åŒæ°ãšããŠã§ã¯ãªããååã§ãã©ã¡ãŒã¿ãŒé åãæž¡ããŸãã
åç
§ã«å±æ§ããªãå Žåã¯ã䜿çšããã³ãŒãã®åã«å®çŸ©ããŸãã ãã®ãµã³ãã«ã§ã¯ã Compatibility.fsã䜿çšããŸããåç
§ã§æå®ãããŠããå Žåã¯ããã®å®çŸ©ãçç¥ããŸãã
namespace System.Diagnostics.CodeAnalysis
open System
[<Sealed; AttributeUsage(AttributeTargets.Method ||| AttributeTargets.Constructor)>]
type RequireNamedArgumentsAttribute() =
inherit Attribute()
ãªãŒããŒããŒãã®éžæ
æ¢ã«ã©ãããããŠããå€ãšå€ãåºå¥ããããã«ãæãå
·äœçãªã¿ã€ãã¬ãŒã«ãŒã¯ããã以å€ã®å Žåã¯çããã©ã³ã¯ä»ãããããžã§ããªã㯠ãªãŒããŒããŒããæ¯èŒããŸãã ããšãã°ã Task<'T> ã³ã³ã¹ãã©ã¯ã¿ãŒ ãã©ã¡ãŒã¿ãŒã¯ãã㢠'T ãã©ã¡ãŒã¿ãŒãããåªå
ãããŸãã
Note
æãå
·äœçãªã¿ã€ãã¬ãŒã«ãŒãš OverloadResolutionPriorityAttribute ã®ãµããŒã㯠ãF# 11.2 ã®æ©èœã§ãã .NET 11.0.100 SDK ã§ã<LangVersion>preview</LangVersion>ãæå¹ã«ããŸãã
open System.Threading.Tasks
let pending = Task.FromResult 42
let wrapped = ValueTask<_>(pending)
let answer: int = wrapped.Result
// ValueTask<int>, not ValueTask<Task<int>>
æšè«ãããå㯠ValueTask<int>ã§ããã³ã³ã¹ãã©ã¯ã¿ãŒã¯ã Task<int>åã®çµæå€ãšããŠåŠçããã®ã§ã¯ãªããã¿ã¹ã¯ãã©ããããŸãã
ãã®æçµææ®µã«ãŒã«ã§ã¯ãé¢é£ã®ãªãåãŸã㯠SRTP åè£ã¯äžŠã¹æ¿ããããŸããã éžæãæ€æ»ããã«ã¯ã æ å ±èšºæ FS3575 (åªå ãªãŒããŒããŒã) ãš FS3576 (ãã€ãã¹ããããžã§ããªã㯠ãªãŒããŒããŒã) ãæå¹ã«ããŸãã
å€ããã€ã㪠ãšã³ã㪠ãã€ã³ããç¶æããªãããæ°ãããœãŒã¹ ã³ã³ãã€ã«çšã«è±å¯ãª API ãåªå
ããã«ã¯ãã©ã€ãã©ãªäœæè
ãããé«ã System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute å€ãèšå®ã§ããŸãã ãã®çœ®æã§ã¯ãåŒã³åºãå
ã®ãœãŒã¹è¡ãæ¢åã® CallerLineNumber æ©èœãéããŠèšé²ãããŸãã
open System.Runtime.CompilerServices
type Check =
static member That(condition: bool) =
if condition then "OK" else "Check failed."
[<OverloadResolutionPriority(1)>]
static member That(condition: bool, [<CallerLineNumber>] ?line: int) =
if condition then "OK" else $"Check failed at line {defaultArg line 0}."
let stock = 0
let diagnostic = Check.That(stock > 0)
// The diagnostic includes the caller's source line.
åªå é äœ 1 ã¯ãè¡å¯Ÿå¿ã®ãªãŒããŒããŒããéžæããŸãã屿§ããªãå Žåã¯ã1 ãã©ã¡ãŒã¿ãŒãªãŒããŒããŒããåªå ãããŸãã æªæå®ã®ã¡ã³ããŒã®åªå 床㯠0 ã§ãã 屿§ã¯ã.NET 9 以éã®åç §ã§äœ¿çšã§ããŸãã
åªå 床ãã£ã«ã¿ãŒã¯ãéåžžã®ãªãŒããŒããŒãã«ãŒã«ã®åã«å®£èšåå ã®é©çšå¯èœãªåè£ããã£ã«ã¿ãŒåŠçããŸããçããåªå é äœã§ã¯ããããã®ã«ãŒã«ã䜿çšãããŸãã æ¡åŒµã¢ãžã¥ãŒã«ãã©ã³ã¯ä»ãããããããããã£/ã€ã³ãã¯ãµãŒã®éžæã倿Žãããããããšã¯ãããŸããã ãã®æ©èœãæå¹ã«ãããšããªãŒããŒã©ã€ãã§å±æ§ãäŒéã§ããªããªããŸãã 䜿çšããŠããã³ã³ãã€ã©ã®ã¿ããåªå 床ãé©çšããããã«æ©èœãæå¹ã«ããå¿ èŠããããŸãã
æ»ãå€ã®åã§éžæ
åŒã³åºãå
ãå¿
èŠãšããã³ã³ãããŒã«ãã¬ãŒã³ãªå€ãæ§ç¯ããããã«ãFSharp.Core 11 ã® AllowOverloadOnReturnType 屿§ã䜿çšãããšãäºæãããçµæã®åããªãŒããŒããŒãã®éžæã«åå ã§ããããã«ãªããŸãã ãã®å±æ§ã«ã¯ãã¬ãã¥ãŒã¯å¿
èŠãããŸããã
type Inject =
[<AllowOverloadOnReturnType>]
static member Pure(value: 'T) : 'T list = [value]
[<AllowOverloadOnReturnType>]
static member Pure(value: 'T) : 'T option = Some value
let batch: string list = Inject.Pure "ready"
let optional: string option = Inject.Pure "ready"
// ["ready"] and Some "ready"
çµæã«æ³šéãä»ããŠããªã¹ããŸãã¯ãªãã·ã§ã³ãéžæããŸãã 屿§ãŸãã¯æ¢ç¥ã®çµæã®åããªãå ŽåãåŒã³åºãã¯ãããŸãã§ãã ãããã£ãŠãæ»ãå€ã®ã¿ã®ãªãŒããŒããŒãã远å ãããšãæšè«ãããåŒã³åºããäžæãããå¯èœæ§ããããŸãã ããã¯ãåºåã®çš®é¡ã§ã¡ã³ããŒãéžæãã æ§é æ§é ãšã¯ç°ãªããŸãã
çç¥å¯èœãªãã©ã¡ãŒã¿ãŒ
F# ã§ã¯ãã¡ãœããã«å¯Ÿã㊠2 ã€ã®ç°ãªã圢åŒã®çç¥å¯èœãªãã©ã¡ãŒã¿ãŒããµããŒããããããããç°ãªãç®çãæäŸãããŸãã
- çç¥å¯èœãªãã©ã¡ãŒã¿ãŒ (F# ãã€ãã£ã)
- çç¥å¯èœãªãã©ã¡ãŒã¿ãŒ (C# çžäºéçš)
çç¥å¯èœãªãã©ã¡ãŒã¿ãŒ (F# ãã€ãã£ã)
ãã©ã¡ãŒã¿ãŒåã®åã«çå笊ã䜿çšããŠãã¡ãœããã®çç¥å¯èœãªãã©ã¡ãŒã¿ãŒãæå®ã§ããŸãã åŒã³åºãå
ã®èŠç¹ãããçç¥å¯èœãªãã©ã¡ãŒã¿ãŒã¯ F# ã®ãªãã·ã§ã³åãšããŠè§£éãããã®ã§ããããã«å¯Ÿããã¯ãšãªã¯ãmatch ããã³ Some ã§ None åŒã䜿çšããŠããªãã·ã§ã³åã®ã¯ãšãªãå®è¡ããéåžžã®æ¹æ³ã§å®è¡ã§ããŸãã çç¥å¯èœãªãã©ã¡ãŒã¿ãŒã¯ãlet ãã€ã³ãã£ã³ã°ã䜿çšããŠäœæããã颿°ã§ã¯ãªããã¡ã³ããŒã«å¯ŸããŠã®ã¿èš±å¯ãããŸãã
?arg=Noneã?arg=Some(3)ã?arg=arg ãªã©ã®ãã©ã¡ãŒã¿ãŒåã䜿çšããŠãæ¢åã®çç¥å¯èœãªå€ãã¡ãœããã«æž¡ãããšãã§ããŸãã ããã¯ãçç¥å¯èœãªåŒæ°ãå¥ã®ã¡ãœããã«æž¡ãã¡ãœãããäœæããå Žåã«åœ¹ç«ã€å¯èœæ§ããããŸãã
ãŸããã·ã£ããŠåŠçã䜿çšããŠçç¥å¯èœãªåŒæ°ã®æ¢å®å€ãèšå®ãã颿° defaultArgã䜿çšããããšãã§ããŸãã
defaultArg 颿°ã§ã¯ãçç¥å¯èœãªãã©ã¡ãŒã¿ãŒãæåã®åŒæ°ãšããŠãæ¢å®å€ã 2 çªç®ã®åŒæ°ãšããŠåãåããŸãã C# ã¹ã¿ã€ã«ã®æ¡åŒµæ©èœãšã¯ç°ãªãããã®é¢æ°ã䜿çšãããšãã¡ãœããã®äœæè
ã¯ãåŒã³åºãå
ãå€ãæž¡ãããã©ããã確èªã§ããŸãã
çç¥å¯èœãªãã©ã¡ãŒã¿ãŒã®äœ¿çšäŸã次ã«ç€ºããŸãã
type DuplexType =
| Full
| Half
type Connection(?rate0 : int, ?duplex0 : DuplexType, ?parity0 : bool) =
let duplex = defaultArg duplex0 Full
let parity = defaultArg parity0 false
let mutable rate = match rate0 with
| Some rate1 -> rate1
| None -> match duplex with
| Full -> 9600
| Half -> 4800
do printfn "Baud Rate: %d Duplex: %A Parity: %b" rate duplex parity
let conn1 = Connection(duplex0 = Full)
let conn2 = Connection(duplex0 = Half)
let conn3 = Connection(300, Half, true)
let conn4 = Connection(?duplex0 = None)
let conn5 = Connection(?duplex0 = Some(Full))
let optionalDuplexValue : option<DuplexType> = Some(Half)
let conn6 = Connection(?duplex0 = optionalDuplexValue)
åºåã¯æ¬¡ã®ãšããã§ãã
Baud Rate: 9600 Duplex: Full Parity: false
Baud Rate: 4800 Duplex: Half Parity: false
Baud Rate: 300 Duplex: Half Parity: true
Baud Rate: 9600 Duplex: Full Parity: false
Baud Rate: 9600 Duplex: Full Parity: false
Baud Rate: 4800 Duplex: Half Parity: false
屿§ãé©çšããŠãçç¥å¯èœãªãã©ã¡ãŒã¿ãŒã [<Struct>] åã«æå®ããããšãã§ããŸãã
type T() =
static member M([<Struct>] ?p : string) =
match p with
| ValueSome s -> printfn "%s" s
| ValueNone -> printfn "None"
äžèšã®ããã«ãæ§é äœã«åºã¥ãçç¥å¯èœãªãã©ã¡ãŒã¿ãŒã䜿çšããå Žåã¯ãdefaultValueArgã®ä»£ããã« defaultArg ã䜿çšããŠãã©ã¡ãŒã¿ãŒã®æ¢å®å€ãèšå®ããŸãã
çç¥å¯èœãªãã©ã¡ãŒã¿ãŒ (C# çžäºéçš)
C# çžäºéçšã®ããã«ãF# ã§ [<Optional; DefaultParameterValue<(...)>] 屿§ã䜿çšããŠãåŒã³åºãå
ãåŒæ°ãçç¥å¯èœãšèŠãªãããšãã§ããããã«ããããšãã§ããŸãã ããã¯ãMyMethod(int i = 3) ã®ããã«ãC# ã§åŒæ°ãçç¥å¯èœãšããŠå®çŸ©ããããšãšåãã§ãã ãã®ãã©ãŒã ã¯ãC# ã³ãŒããšã®çžäºéçšã容æã«ããããã« F# 4.1 ã§å°å
¥ãããŸããã
open System
open System.Runtime.InteropServices
type C =
static member Foo([<Optional; DefaultParameterValue("Hello world")>] message) =
printfn $"{message}"
ãŸããæ°ãããªããžã§ã¯ããæ¢å®ã®ãã©ã¡ãŒã¿ãŒå€ãšããŠæå®ããããšãã§ããŸãã ããšãã°ãFoo ã¡ã³ããŒã¯ä»£ããã«çç¥å¯èœãª CancellationToken ãå
¥åãšããŠäœ¿çšã§ããŸãã
open System.Threading
open System.Runtime.InteropServices
type C =
static member Foo([<Optional; DefaultParameterValue(CancellationToken())>] ct: CancellationToken) =
printfn $"{ct}"
DefaultParameterValue ã®åŒæ°ãšããŠæå®ãããå€ã¯ããã©ã¡ãŒã¿ãŒã®åãšäžèŽããå¿
èŠããããŸãã ããšãã°ã以äžã¯èš±å¯ãããŸããã
type C =
static member Wrong([<Optional; DefaultParameterValue("string")>] i:int) = ()
ãã®å Žåãã³ã³ãã€ã©ã«ãã£ãŠèŠåãçæãããäž¡æ¹ã®å±æ§ãå®å
šã«ç¡èŠãããŸãã æ¢å®å€ null åæ³šéãä»ããå¿
èŠãããããšã«æ³šæããŠãã ããããã以å€ã®å Žåãã³ã³ãã€ã©ã¯ééã£ãå (ã€ãŸãã [<Optional; DefaultParameterValue(null:obj)>] o:obj) ãæšè«ããŸãã
åç §æž¡ã
åç §ã«ãã F# å€ã®åãæž¡ãã«ã¯ããããŒãžã ãã€ã³ã¿ãŒåã§ãã byref ãé¢ä¿ããŸãã 䜿çšããåã«é¢ããã¬ã€ãã³ã¹ã¯æ¬¡ã®ãšããã§ãã
- ãã€ã³ã¿ãŒã®èªã¿åãã®ã¿ãå¿
èŠãªå Žåã¯ã
inref<'T>ã䜿çšããŸãã - ãã€ã³ã¿ãŒãžã®æžã蟌ã¿ã®ã¿ãå¿
èŠãªå Žåã¯ã
outref<'T>ã䜿çšããŸãã - ãã€ã³ã¿ãŒã®èªã¿åããšæžã蟌ã¿ã®äž¡æ¹ãè¡ãå¿
èŠãããå Žåã¯ã
byref<'T>ã䜿çšããŸãã
let example1 (x: inref<int>) = printfn $"It's %d{x}"
let example2 (x: outref<int>) = x <- x + 1
let example3 (x: byref<int>) =
printfn $"It's %d{x}"
x <- x + 1
let test () =
// No need to make it mutable, since it's read-only
let x = 1
example1 &x
// Needs to be mutable, since we write to it
let mutable y = 2
example2 &y
example3 &y // Now 'y' is 3
ãã©ã¡ãŒã¿ãŒã¯ãã€ã³ã¿ãŒã§ãããå€ã¯å€æŽå¯èœã§ãããããå€ã«å¯Ÿãã倿Žã¯ã颿°ã®å®è¡åŸãä¿æãããŸãã
æ»ãå€ãšããŠã¿ãã«ã䜿çšããŠã.NET ã©ã€ãã©ãª ã¡ãœããã«ä»»æã® out ãã©ã¡ãŒã¿ãŒãæ ŒçŽã§ããŸãã ãŸãã¯ãout ãã©ã¡ãŒã¿ãŒã byref ãã©ã¡ãŒã¿ãŒãšããŠæ±ãããšãã§ããŸãã äž¡æ¹ã®æ¹æ³ã次ã®ã³ãŒãäŸã«ç€ºããŸãã
// TryParse has a second parameter that is an out parameter
// of type System.DateTime.
let (b, dt) = System.DateTime.TryParse("12-20-04 12:21:00")
printfn "%b %A" b dt
// The same call, using an address of operator.
let mutable dt2 = System.DateTime.Now
let b2 = System.DateTime.TryParse("12-20-04 12:21:00", &dt2)
printfn "%b %A" b2 dt2
ãã©ã¡ãŒã¿ãŒé å
å Žåã«ãã£ãŠã¯ãä»»æã®æ°ã®ç°çš®åã®ãã©ã¡ãŒã¿ãŒãåãåã颿°ãå®çŸ©ããå¿
èŠããããŸãã å¯èœãªãã¹ãŠã®ãªãŒããŒããŒããããã¡ãœãããäœæããŠã䜿çšå¯èœãªãã¹ãŠã®åãèæ
®ããããšã¯å®éçã§ã¯ãããŸããã .NET å®è£
ã§ã¯ããã©ã¡ãŒã¿ãŒé
åæ©èœã䜿çšããŠããã®ãããªã¡ãœããããµããŒããããŠããŸãã ã·ã°ããã£å
ã§ãã©ã¡ãŒã¿ãŒé
åãåãåãã¡ãœããã«ã¯ãä»»æã®åæ°ã®ãã©ã¡ãŒã¿ãŒãæå®ã§ããŸãã ãã©ã¡ãŒã¿ãŒã¯é
åã«æ ŒçŽãããŸãã é
åèŠçŽ ã®åã«ãã£ãŠã颿°ã«æž¡ãããšãã§ãããã©ã¡ãŒã¿ãŒã®åãæ±ºãŸããŸãã èŠçŽ ã®åãšã㊠System.Object ã䜿çšããŠãã©ã¡ãŒã¿ãŒé
åãå®çŸ©ãããšãã¯ã©ã€ã¢ã³ã ã³ãŒãã§ä»»æã®åã®å€ãæž¡ãããšãã§ããŸãã
F# ã§ã¯ããã©ã¡ãŒã¿ãŒé åã¯ã¡ãœããå ã§ã®ã¿å®çŸ©ã§ããŸãã ãããã¯ãã¹ã¿ã³ãã¢ãã³é¢æ°ããŸãã¯ã¢ãžã¥ãŒã«å ã§å®çŸ©ãããŠãã颿°ã§ã¯äœ¿çšã§ããŸããã
ãã ããprintfn ã®ãããªé¢æ°ã¯ãæžåŒæå®åãšåæšè«ã䜿çšããŠè€æ°ã®åŒæ°ãåçã«åŠçããããšã§ãåæ§ã®åäœãå®çŸããŸãã
printfn 颿°ã¯ãã©ã¡ãŒã¿ãŒé
åã«äŸåããŸããã代ããã«ãF# ã®åã»ãŒããªæžåŒèšå®ã¡ã«ããºã ã䜿çšããŠãã³ã³ãã€ã«æã®åãã§ãã¯ã確å®ã«ããªãããããŸããŸãªæ°ã®åŒæ°ãåŠçããŸãã
ãã©ã¡ãŒã¿ãŒé
åã¯ãParamArray 屿§ã䜿çšããŠå®çŸ©ããŸãã
ParamArray 屿§ã¯ãæåŸã®ãã©ã¡ãŒã¿ãŒã«ã®ã¿é©çšã§ããŸãã
次ã®ã³ãŒãã¯ããã©ã¡ãŒã¿ãŒé åãåãåã .NET ã¡ãœãããšããã©ã¡ãŒã¿ãŒé åãåãåãã¡ãœãããæã€ F# ã®åã®å®çŸ©ã®äž¡æ¹ãåŒã³åºãæ¹æ³ã瀺ããŠããŸãã
open System
type X() =
member this.F([<ParamArray>] args: Object[]) =
for arg in args do
printfn "%A" arg
[<EntryPoint>]
let main _ =
// call a .NET method that takes a parameter array, passing values of various types
Console.WriteLine("a {0} {1} {2} {3} {4}", 1, 10.0, "Hello world", 1u, true)
let xobj = new X()
// call an F# method that takes a parameter array, passing values of various types
xobj.F("a", 1, 10.0, "Hello world", 1u, true)
0
ãããžã§ã¯ãå ã§å®è¡ãããšãåã®ã³ãŒãã®åºåã¯æ¬¡ã®ããã«ãªããŸãã
a 1 10 Hello world 1 True
"a"
1
10.0
"Hello world"
1u
true