Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
F# 6 ã§ã¯ãF# èšèªãš F# Interactive ã«ããã€ãã®æ©èœåŒ·åã远å ãããŠããŸãã .NET 6 ã§ãªãªãŒã¹ãããŸãã
ææ°ã® .NET SDK 㯠ã.NET ããŠã³ããŒã ããŒãžããããŠã³ããŒãã§ããŸãã
æŠèŠ
F# 6 ã¯ããã¹ãŠã® .NET Core ãã£ã¹ããªãã¥ãŒã·ã§ã³ãš Visual Studio ããŒã«ã§äœ¿çšã§ããŸãã 詳现ã«ã€ããŠã¯ãã F# ã®æŠèŠããåç §ããŠãã ããã
ã¿ã¹ã¯ {...}
F# 6 ã«ã¯ã ã¿ã¹ã¯åŒã䜿çšã㊠F# ã³ãŒãã§ .NET ã¿ã¹ã¯ãäœæããããã®ãã€ãã£ã ãµããŒããå«ãŸããŠããŸãã ã¿ã¹ã¯åŒã¯éåæåŒã«äŒŒãŠããŸããã.NET ã¿ã¹ã¯ãçŽæ¥äœæã§ããŸãã
ããšãã°ã.NETäºæã®ã¿ã¹ã¯ãäœæããããã®æ¬¡ã®F#ã³ãŒããèããŠã¿ãŠãã ããã
let readFilesTask (path1, path2) =
async {
let! bytes1 = File.ReadAllBytesAsync(path1) |> Async.AwaitTask
let! bytes2 = File.ReadAllBytesAsync(path2) |> Async.AwaitTask
return Array.append bytes1 bytes2
} |> Async.StartAsTask
F# 6 ã䜿çšãããšããã®ã³ãŒããæ¬¡ã®ããã«æžãæããããšãã§ããŸãã
let readFilesTask (path1, path2) =
task {
let! bytes1 = File.ReadAllBytesAsync(path1)
let! bytes2 = File.ReadAllBytesAsync(path2)
return Array.append bytes1 bytes2
}
åªãã TaskBuilder.fs ã©ã€ãã©ãªãš Ply ã©ã€ãã©ãªãéããŠãF# 5 ã§ã¿ã¹ã¯ã®ãµããŒããå©çšã§ããŸãã çµã¿èŸŒã¿ã®ãµããŒãã«ã³ãŒããç§»è¡ããã®ã¯ç°¡åã§ãã ãã ããããã€ãã®éãããããŸããåå空éãšåæšè«ã¯ãçµã¿èŸŒã¿ã®ãµããŒããšãããã®ã©ã€ãã©ãªã®éã§è¥å¹²ç°ãªããããã€ãã®è¿œå ã®å泚éãå¿ èŠã«ãªãå ŽåããããŸãã å¿ èŠã«å¿ããŠããããã®ã³ãã¥ãã㣠ã©ã€ãã©ãªã F# 6 ã§æç€ºçã«åç §ããåãã¡ã€ã«ã§æ£ããåå空éãéãå Žåã¯ãåŒãç¶ã F# 6 ã§äœ¿çšã§ããŸãã
task {âŠ}ã®äœ¿çšã¯ãasync {âŠ}ã®äœ¿çšãšãã䌌ãŠããŸãã
task {âŠ}ã®äœ¿çšã«ã¯ãasync {âŠ}ãããããã€ãã®å©ç¹ããããŸãã
-
task {...}ã®ãªãŒããŒããããäœããªããéåæåŠçãè¿ éã«å®è¡ãããããã ã³ãŒã ãã¹ã®ããã©ãŒãã³ã¹ãåäžããå¯èœæ§ããããŸãã -
task {âŠ}çšã®ã¹ãããå®è¡ãšã¹ã¿ãã¯ãã¬ãŒã¹ã®ãããã°ãããè¯å¥œã§ãã - ã¿ã¹ã¯ãæ³å®ãŸãã¯çæãã .NET ããã±ãŒãžãšã®çžäºéçšã容æã«ãªããŸãã
async {âŠ}ã«æ
£ããŠããå Žåã¯ã次ã®ç¹ã«æ³šæããå¿
èŠããããŸãã
-
task {âŠ}ã¯ãã¿ã¹ã¯ãæåã®åŸ æ©ãã€ã³ããŸã§çŽã¡ã«å®è¡ããŸãã -
task {âŠ}ã¯ãã£ã³ã»ã« ããŒã¯ã³ãæé»çã«äŒéããŸããã -
task {âŠ}ã§ã¯ãæé»çãªåãæ¶ããã§ãã¯ã¯å®è¡ãããŸããã -
task {âŠ}ã¯éåæã®ããŒã«ã³ãŒã«ããµããŒãããŠããŸããã ã€ãŸããreturn! ..ãååž°çã«äœ¿çšãããšãäžéã®éåæåŸ æ©ããªãå Žåã«ã¹ã¿ã㯠ãªãŒããŒãããŒãçºçããå¯èœæ§ããããŸãã
äžè¬ã«ãã¿ã¹ã¯ã䜿çšãã .NET ã©ã€ãã©ãªãšçžäºéçšããå Žåããéåæã³ãŒã ã®ããŒã«ã³ãŒã«ãæé»çãªãã£ã³ã»ã« ããŒã¯ã³ã®äŒéã«äŸåããªãå Žåã¯ãæ°ããã³ãŒãã§task {âŠ}ãããasync {âŠ}ã䜿çšããããšãæ€èšããå¿
èŠããããŸãã æ¢åã®ã³ãŒãã§ã¯ãåã«èª¬æããtask {âŠ}ã®ç¹æ§ã«äŸåããªãããã«ã³ãŒãã確èªããåŸã«ã®ã¿ãasync {âŠ}ã«åãæ¿ããå¿
èŠããããŸãã
ãã®æ©èœã¯ ãF# RFC FS-1097 ãå®è£ ããŸãã
ã䜿çšããç°¡åãªã€ã³ããã¯ã¹äœææ§æ expr[idx]
F# 6 ã§ã¯ãã³ã¬ã¯ã·ã§ã³ã®ã€ã³ããã¯ã¹äœæãšã¹ã©ã€ã¹ã®æ§æ expr[idx] ã䜿çšã§ããŸãã
F# 5 ãŸã§ãF# ã§ã¯ã€ã³ããã¯ã¹äœææ§æãšã㊠expr.[idx] ã䜿çšãããŠããŸãã
expr[idx]ã®äœ¿çšãèš±å¯ããããšã¯ãF# ãåŠç¿ãã人ãåã㊠F# ã«è§Šãã人ããã®ãã£ãŒãããã¯ã«åºã¥ããŠããŸãã圌ãã®å€ãã¯ãããã衚èšã®ã€ã³ããã¯ã¹ä»ãã®äœ¿çšãæ¥çæšæºããã®äžèŠãªéžè±ãšæããŠããŸãã
æ¢å®ã§ã¯ã expr.[idx]ã®äœ¿çšã«é¢ããèŠåã¯çæãããªããããããã¯ç Žå£ç倿Žã§ã¯ãããŸããã ãã ããã³ãŒãã®æç¢ºåã瀺åããäžéšã®æ
å ±ã¡ãã»ãŒãžãåºåãããŸãã å¿
èŠã«å¿ããŠãããã«æ
å ±ã¡ãã»ãŒãžãã¢ã¯ãã£ãåããããšãã§ããŸãã ããšãã°ããªãã·ã§ã³ã®æ
å ±èŠå (/warnon:3366) ãã¢ã¯ãã£ãã«ããŠã expr.[idx] 衚èšã®äœ¿çšã®ã¬ããŒããéå§ã§ããŸãã 詳现ã«ã€ããŠã¯ãã ã€ã³ãã¯ãµãŒè¡šèšããåç
§ããŠãã ããã
æ°ããã³ãŒãã§ã¯ãã€ã³ããã¯ã¹äœææ§æãšã㊠expr[idx] ãäœç³»çã«äœ¿çšããããšããå§ãããŸãã
ãã®æ©èœã¯ ãF# RFC FS-1110 ãå®è£ ããŸãã
éšåã¢ã¯ãã£ã ãã¿ãŒã³ã®æ§é äœè¡šçŸ
F# 6 ã§ã¯ãéšåã¢ã¯ãã£ã ãã¿ãŒã³ã®ãªãã·ã§ã³ã®æ§é äœè¡šçŸã䜿çšããŠã"ã¢ã¯ãã£ã ãã¿ãŒã³" æ©èœãæ¡åŒµããŸãã ããã«ããã屿§ã䜿çšããŠéšåçãªã¢ã¯ãã£ã ãã¿ãŒã³ãå¶çŽããå€ãªãã·ã§ã³ãè¿ãããšãã§ããŸãã
[<return: Struct>]
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| true, int -> ValueSome(int)
| _ -> ValueNone
屿§ã®äœ¿çšãå¿ èŠã§ãã 䜿çšãµã€ãã§ã¯ãã³ãŒãã¯å€æŽãããŸããã çµæãšããŠãå²ãåœãŠãæžããŸãã
ãã®æ©èœã¯ ãF# RFC FS-1039 ãå®è£ ããŸãã
èšç®åŒã«ããããªãŒããŒããŒããããã«ã¹ã¿ã æäœ
F# 6 ã§ã¯ããªãŒããŒããŒããããã¡ãœããã§ CustomOperationAttribute ã䜿çšã§ããŸãã
ã³ã³ãã¥ããŒã·ã§ã³åŒãã«ã㌠contentã®æ¬¡ã®äœ¿çšãæ€èšããŠãã ããã
let mem = new System.IO.MemoryStream("Stream"B)
let content = ContentBuilder()
let ceResult =
content {
body "Name"
body (ArraySegment<_>("Email"B, 0, 5))
body "Password"B 2 4
body "BYTES"B
body mem
body "Description" "of" "content"
}
ããã§ã¯ã body ã«ã¹ã¿ã æäœã¯ãããŸããŸãªåã®åŒæ°ã®æ°ãåãåããŸãã ããã¯ããªãŒããŒããŒãã䜿çšããæ¬¡ã®ãã«ããŒã®å®è£
ã§ãµããŒããããŠããŸãã
type Content = ArraySegment<byte> list
type ContentBuilder() =
member _.Run(c: Content) =
let crlf = "\r\n"B
[|for part in List.rev c do
yield! part.Array[part.Offset..(part.Count+part.Offset-1)]
yield! crlf |]
member _.Yield(_) = []
[<CustomOperation("body")>]
member _.Body(c: Content, segment: ArraySegment<byte>) =
segment::c
[<CustomOperation("body")>]
member _.Body(c: Content, bytes: byte[]) =
ArraySegment<byte>(bytes, 0, bytes.Length)::c
[<CustomOperation("body")>]
member _.Body(c: Content, bytes: byte[], offset, count) =
ArraySegment<byte>(bytes, offset, count)::c
[<CustomOperation("body")>]
member _.Body(c: Content, content: System.IO.Stream) =
let mem = new System.IO.MemoryStream()
content.CopyTo(mem)
let bytes = mem.ToArray()
ArraySegment<byte>(bytes, 0, bytes.Length)::c
[<CustomOperation("body")>]
member _.Body(c: Content, [<ParamArray>] contents: string[]) =
List.rev [for c in contents -> let b = Text.Encoding.ASCII.GetBytes c in ArraySegment<_>(b,0,b.Length)] @ c
ãã®æ©èœã¯ ãF# RFC FS-1056 ãå®è£ ããŸãã
"as" ãã¿ãŒã³
F# 6 ã§ã¯ã as ãã¿ãŒã³ã®å³åŽããã¿ãŒã³ã«ãªããŸãã ããã¯ãåãã¹ãã§å
¥åã«å¯ŸããŠãã匷åãªåãäžããããŠããå Žåã«éèŠã§ãã ããšãã°ã次ã®ã³ãŒããèããŠã¿ãŸãããã
type Pair = Pair of int * int
let analyzeObject (input: obj) =
match input with
| :? (int * int) as (x, y) -> printfn $"A tuple: {x}, {y}"
| :? Pair as Pair (x, y) -> printfn $"A DU: {x}, {y}"
| _ -> printfn "Nope"
let input = box (1, 2)
åãã¿ãŒã³ã®å Žåãå
¥åãªããžã§ã¯ãã¯åãã¹ããããŸãã
as ãã¿ãŒã³ã®å³åŽã«ã¯ãããã«å¥ã®ãã¿ãŒã³ãæå®ããããšãã§ããããèªäœããã匷åãªåã®ãªããžã§ã¯ããšäžèŽããããšãå¯èœã«ãªããŸããã
ãã®æ©èœã¯ ãF# RFC FS-1105 ãå®è£ ããŸãã
ã€ã³ãã³ãæ§æã®ä¿®æ£
F# 6 ã§ã¯ãã€ã³ãã³ãã«å¯Ÿå¿ããæ§æã®äœ¿çšã«é¢ããå€ãã®äžæŽåãšå¶éãåãé€ããŸãã RFC FS-1108 ãåç §ããŠãã ããã ããã«ãããF# 4.0 以éã® F# ãŠãŒã¶ãŒã«ãã£ãŠåŒ·èª¿è¡šç€ºããã 10 ã®éèŠãªåé¡ã解決ãããŸãã
ããšãã°ãF# 5 ã§ã¯ã次ã®ã³ãŒããèš±å¯ãããŸããã
let c = (
printfn "aaaa"
printfn "bbbb"
)
ãã ããæ¬¡ã®ã³ãŒãã¯èš±å¯ãããŸããã§ãã (èŠåãçæãããŸãã)ã
let c = [
1
2
]
F# 6 ã§ã¯ãã©ã¡ããèš±å¯ãããŠããŸãã ããã«ãããF# ã®åŠç¿ãç°¡åã«ãªããåŠç¿ãããããªããŸãã F# ã³ãã¥ããã£ã®å ±åäœæè ã§ãã Hadrian Tang ã¯ããã®æ©èœã®é¡èã§éåžžã«è²Žéãªäœç³»çãªãã¹ããå«ãããã®æ¹æ³ãäž»å°ããŠããŸããã
ãã®æ©èœã¯ ãF# RFC FS-1108 ãå®è£ ããŸãã
远å ã®æé»çãªå€æ
F# 6 ã§ã¯ã RFC FS-1093 ã§èª¬æãããŠããããã«ã远å ã® "æé»ç" ããã³ "åæå" 倿ã®ãµããŒããã¢ã¯ãã£ãåãããŸããã
ãã®å€æŽã«ã¯ã次㮠3 ã€ã®å©ç¹ããããŸãã
- å¿ èŠãªæç€ºçãªã¢ãããã£ã¹ãã®æ°ãæžãããŸã
- å¿ èŠãªæç€ºçãªæŽæ°å€æã®æ°ãæžãããŸã
- .NETã¹ã¿ã€ã«ã®æé»çãªå倿ã«å¯Ÿãããã¡ãŒã¹ãã¯ã©ã¹ã®ãµããŒãã远å ããã
ãã®æ©èœã¯ ãF# RFC FS-1093 ãå®è£ ããŸãã
远å ã®æé»çãªã¢ãããã£ã¹ã倿
F# 6 ã§ã¯ã远å ã®æé»çãªã¢ãããã£ã¹ã倿ãå®è£ ãããŠããŸãã ããšãã°ãF# 5 以åã®ããŒãžã§ã³ã§ã¯ãåæ³šéãååšããå Žåã§ããåŒãç°ãªãåå²ã§ç°ãªããµãã¿ã€ããæã€é¢æ°ãå®è£ ãããšãã«ãæ»ãå€ã®åŒã«ã¢ãããã£ã¹ããå¿ èŠã§ããã æ¬¡ã® F# 5 ã³ãŒãã«ã€ããŠèããŠã¿ãŸãããã
open System
open System.IO
let findInputSource () : TextReader =
if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
// On Monday a TextReader
Console.In
else
// On other days a StreamReader
File.OpenText("path.txt") :> TextReader
ããã§ã¯ãæ¡ä»¶ä»ãæã®åå²ããããã TextReader ãš StreamReader ãèšç®ããäž¡æ¹ã®åå²ã« StreamReader åãæãããããã«ã¢ãããã£ã¹ãã远å ãããŸããã F# 6 ã§ã¯ããããã®ã¢ãããã£ã¹ããèªåçã«è¿œå ãããããã«ãªããŸããã ããã¯ãã³ãŒããç°¡åã§ããããšãæå³ããŸãã
let findInputSource () : TextReader =
if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
// On Monday a TextReader
Console.In
else
// On other days a StreamReader
File.OpenText("path.txt")
å¿
èŠã«å¿ããŠãèŠå /warnon:3388 ãæå¹ã«ããŠãæé»çãªå€æã®ãªãã·ã§ã³ã®èŠåã§èª¬æãããŠããããã«ã远å ã®æé»çãªã¢ãããã£ã¹ãã䜿çšããããã³ã« èŠåã衚瀺ã§ããŸãã
æé»çãªæŽæ°å€æ
F# 6 ã§ã¯ãäž¡æ¹ã®åãæ¢ç¥ã®å Žåã32 ãããæŽæ°ã¯ 64 ãããæŽæ°ã«æ¡å€§ãããŸãã ããšãã°ãäžè¬ç㪠API ã®åœ¢ç¶ãèããŠã¿ãŸãã
type Tensor(âŠ) =
static member Create(sizes: seq<int64>) = Tensor(âŠ)
F# 5 ã§ã¯ãint64 ã®æŽæ°ãªãã©ã«ã䜿çšããå¿ èŠããããŸãã
Tensor.Create([100L; 10L; 10L])
åã¯
Tensor.Create([int64 100; int64 10; int64 10])
F# 6 ã§ã¯ãint32ããint64ãžã®æ¡å€§ãint32ãžã®nativeintãint32ãžã®doubleãèªåçã«è¡ãããŸããããã¯ãåã®æšè«äžã«ãœãŒã¹ãšå®å
ã®äž¡æ¹ã®åãããã£ãŠããå Žåã§ãã ãã®ãããåã®äŸã®ãããªå Žåã¯ã int32 ãªãã©ã«ã䜿çšã§ããŸãã
Tensor.Create([100; 10; 10])
ãã®å€æŽã«ãããããããã»ãšãã©ã®å ŽåãF# ã¯æ°å€åã®æç€ºçãªæ¡å€§ãåŒãç¶ã䜿çšããŸãã ããšãã°ãæé»çãªæ¡å€§ã¯ã int8 ã int16ãªã©ã®ä»ã®æ°å€åã float32 ãã float64ããŸãã¯ãœãŒã¹ãŸãã¯å®å
ã®åãäžæãªå Žåã«ã¯é©çšãããŸããã æé»çãªå€æã®ãªãã·ã§ã³ã®èŠåã®èª¬æã«åŸã£ãŠãèŠå /warnon:3389 ãæå¹ã«ããŠãæé»çãªæ°å€æ¡å€§ã䜿çšããããã¹ãŠã®æç¹ã§ èŠåã衚瀺ããããšãã§ããŸãã
.NETã¹ã¿ã€ã«ã®æé»çãªå€æã«å¯ŸããåªãããµããŒã
F# 6 ã§ã¯ã.NET ã® "op_Implicit" 倿ã¯ãã¡ãœãããåŒã³åºããšãã« F# ã³ãŒãã§èªåçã«é©çšãããŸãã ããšãã°ãF# 5 ã§ã¯ãXML çšã® .NET API ã䜿çšãããšãã« XName.op_Implicit ã䜿çšããå¿
èŠããããŸãã
open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants(XName.op_Implicit "Item")
F# 6 ã§ã¯ããœãŒã¹åŒãšã¿ãŒã²ããåã§åã䜿çšã§ããå Žåã op_Implicit 倿ãåŒæ°åŒã«èªåçã«é©çšãããŸãã
open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants("Item")
ãªãã·ã§ã³ã§ããæé»çãªå€æã®ãªãã·ã§ã³ã®èŠåãã§èª¬æãããŠããããã«ãæ¡å€§å€æãã¡ãœããåŒæ°ã§äœ¿çš/warnon:3395ãã¹ãŠã®æç¹ã§èŠåã衚瀺ããããã«op_Implicitãæå¹ã«ããããšãã§ããŸãã
泚
F# 6 ã®æåã®ãªãªãŒã¹ã§ã¯ããã®èŠåçªå·ã¯ /warnon:3390 ã§ããã ç«¶åã®ãããèŠåçªå·ã¯åŸã§ /warnon:3395ã«æŽæ°ãããŸããã
æé»çãªå€æã«é¢ãããªãã·ã§ã³ã®èŠå
åäž»å°åå€æãšæé»çãªå€æã¯ãåæšè«ãšååã«ããåãã§ããªãå¯èœæ§ããããçè§£ãé£ããã³ãŒãã«ã€ãªããå¯èœæ§ããããŸãã ãã®ãããF# ã³ãŒãã§ãã®æ©èœãæªçšãããªãããã«ããããã«ãããã€ãã®è»œæžçãååšããŸãã æåã«ããœãŒã¹ãšå®å ã®äž¡æ¹ã®åãå³å¯ã«èªèããå¿ èŠããããŸãããããŸããã远å ã®åæšè«ã¯çºçããŸããã 第 2 ã«ããªããã€ã³èŠåãã¢ã¯ãã£ãã«ããŠãæé»çãªå€æã®äœ¿çšãå ±åã§ããŸããæ¢å®ã§ã¯ 1 ã€ã®èŠåããªã³ã«ãªã£ãŠããŸãã
-
/warnon:3388(远å ã®æé»çãªã¢ãããã£ã¹ã) -
/warnon:3389(æé»çãªæ°å€æ¡å€§) -
/warnon:3391(æ¢å®ã§ã¯ãã¡ãœãã以å€ã®åŒæ°ã§op_Implicitãæå¹) -
/warnon:3395(ã¡ãœããã®åŒæ°å ã§op_Implicitãé©çšããã)
æé»çãªå€æã®ãã¹ãŠã®äœ¿çšãçŠæ¢ããå Žåã¯ã /warnaserror:3388ã /warnaserror:3389ã /warnaserror:3391ã /warnaserror:3395ãæå®ããããšãã§ããŸãã
2 鲿°ã®æžåŒèšå®
F# 6 ã§ã¯ã %B ãã¿ãŒã³ãã2 鲿°åœ¢åŒã§äœ¿çšå¯èœãªæžåŒæå®åã«è¿œå ãããŸãã æ¬¡ã® F# ã³ãŒãã«ã€ããŠèããŠã¿ãŸãããã
printf "%o" 123
printf "%B" 123
ãã®ã³ãŒãã§ã¯ã次ã®åºåãåºåãããŸãã
173
1111011
ãã®æ©èœã¯ ãF# RFC FS-1100 ãå®è£ ããŸãã
äœ¿çšæã®ãã€ã³ãåé€
F# 6 ã§ã¯ã_ ãã€ã³ãã§useã䜿çšã§ããŸããæ¬¡ã«äŸã瀺ããŸãã
let doSomething () =
use _ = System.IO.File.OpenText("input.txt")
printfn "reading the file"
ãã®æ©èœã¯ ãF# RFC FS-1102 ãå®è£ ããŸãã
ã€ã³ã©ã€ã³ã€ãã©ã ã
F# ã³ã³ãã€ã©ã«ã¯ãã³ãŒãã®ã€ã³ã©ã€ã³åãå®è¡ãããªããã£ãã€ã¶ãŒãå«ãŸããŠããŸãã F# 6 ã§ã¯ãã³ãŒããå¿ èŠã«å¿ããŠãåŒæ°ãã©ã ã颿°ã§ãããšå€æãããå Žåããã®åŒæ°èªäœãåžžã«åŒã³åºããµã€ãã§ã€ã³ã©ã€ã³åãããããšãç€ºãæ°ãã宣èšåæ©èœã远å ããŸããã
ããšãã°ã次㮠iterateTwice 颿°ã䜿çšããŠé
åãèµ°æ»ãããšããŸãã
let inline iterateTwice ([<InlineIfLambda>] action) (array: 'T[]) =
for j = 0 to array.Length-1 do
action array[j]
for j = 0 to array.Length-1 do
action array[j]
åŒã³åºããµã€ããæ¬¡ã®å Žå:
let arr = [| 1.. 100 |]
let mutable sum = 0
arr |> iterateTwice (fun x ->
sum <- sum + x)
ãã®åŸãã€ã³ã©ã€ã³åããã®ä»ã®æé©åã®åŸãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
let arr = [| 1.. 100 |]
let mutable sum = 0
for j = 0 to arr.Length-1 do
sum <- sum + arr[j]
for j = 0 to arr.Length-1 do
sum <- sum + arr[j]
以åã®ããŒãžã§ã³ã® F# ãšã¯ç°ãªãããã®æé©åã¯ãé¢ä¿ããã©ã ãåŒã®ãµã€ãºã«é¢ä¿ãªãé©çšãããŸãã ãã®æ©èœã䜿çšããŠãã«ãŒãã®å±éãšåæ§ã®å€æããã確å®ã«å®è£ ããããšãã§ããŸãã
ãªããã€ã³èŠå (/warnon:3517ãæ¢å®ã§ã¯ãªã) ããªã³ã«ãããšãåŒã³åºããµã€ãã§ InlineIfLambda åŒæ°ãã©ã ãåŒã«ãã€ã³ããããŠããªãã³ãŒãå
ã®å Žæã瀺ãããšãã§ããŸãã éåžžã®ç¶æ³ã§ã¯ããã®èŠåãæå¹ã«ããªãã§ãã ããã ãã ããç¹å®ã®çš®é¡ã®é«ããã©ãŒãã³ã¹ ããã°ã©ãã³ã°ã§ã¯ããã¹ãŠã®ã³ãŒããã€ã³ã©ã€ã³åããŠãã©ããåãããšäŸ¿å©ã§ãã
ãã®æ©èœã¯ ãF# RFC FS-1098 ãå®è£ ããŸãã
åéå¯èœãªã³ãŒã
F# 6 ã® task {âŠ} ãµããŒãã¯ã åéå¯èœãªã³ãŒãRFC FS-1087 ãšåŒã°ããåºç€ã«åºã¥ããŠæ§ç¯ãããŠããŸãã åéå¯èœãªã³ãŒãã¯ãããŸããŸãªçš®é¡ã®é«ããã©ãŒãã³ã¹ã®éåæããã³çæç¶æ
ã®ãã·ã³ãæ§ç¯ããããã«äœ¿çšã§ããæè¡çãªæ©èœã§ãã
ãã®ä»ã®ã³ã¬ã¯ã·ã§ã³é¢æ°
FSharp.Core 6.0.0 ã§ã¯ãã³ã¢ ã³ã¬ã¯ã·ã§ã³é¢æ°ã« 5 ã€ã®æ°ããæäœã远å ãããŸãã ãããã®é¢æ°ã¯æ¬¡ã®ãšããã§ãã
- List/Array/Seq.insertAt
- List/Array/Seq.removeAt
- ãªã¹ã/é å/ã·ãŒã±ã³ã¹.updateAt
- List/Array/Seq.insertManyAt
- List/Array/Seq.removeManyAt
ãããã®é¢æ°ã¯ãã¹ãŠã察å¿ããã³ã¬ã¯ã·ã§ã³ã®çš®é¡ãŸãã¯ã·ãŒã±ã³ã¹ã«å¯ŸããŠã³ããŒããã³æŽæ°æäœãå®è¡ããŸãã ãã®çš®é¡ã®æäœã¯ã"æ©èœæŽæ°" ã®åœ¢åŒã§ãã ãããã®é¢æ°ã®äœ¿çšäŸã«ã€ããŠã¯ã察å¿ããããã¥ã¡ã³ã ( List.insertAt ãªã©) ãåç §ããŠãã ããã
ããšãã°ãElmish ã¹ã¿ã€ã«ã§èšè¿°ãããåçŽãª "Todo List" ã¢ããªã±ãŒã·ã§ã³ã®ã¢ãã«ãã¡ãã»ãŒãžãããã³æŽæ°ããžãã¯ã«ã€ããŠèããŠã¿ãŸãããã ããã§ã¯ããŠãŒã¶ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãšå¯Ÿè©±ããã¡ãã»ãŒãžãçæãã update 颿°ã¯ãããã®ã¡ãã»ãŒãžãåŠçããæ°ããã¢ãã«ãçæããŸãã
type Model =
{ ToDo: string list }
type Message =
| InsertToDo of index: int * what: string
| RemoveToDo of index: int
| LoadedToDos of index: int * what: string list
let update (model: Model) (message: Message) =
match message with
| InsertToDo (index, what) ->
{ model with ToDo = model.ToDo |> List.insertAt index what }
| RemoveToDo index ->
{ model with ToDo = model.ToDo |> List.removeAt index }
| LoadedToDos (index, what) ->
{ model with ToDo = model.ToDo |> List.insertManyAt index what }
ãããã®æ°ãã颿°ã䜿çšãããšãããžãã¯ã¯æç¢ºã§ã·ã³ãã«ã§ãããäžå€ããŒã¿ã®ã¿ã«äŸåããŸãã
ãã®æ©èœã¯ ãF# RFC FS-1113 ãå®è£ ããŸãã
ãããã«ããŒãšå€ããã
FSharp.Core 6.0.0 ã§ã¯ã Map åã§ Keys ããããã£ãš Values ããããã£ããµããŒããããããã«ãªããŸããã ãããã®ããããã£ã¯ãåºã«ãªãã³ã¬ã¯ã·ã§ã³ãã³ããŒããŸããã
ãã®æ©èœã¯ ãF# RFC FS-1113 ã«èšèŒãããŠããŸãã
NativePtr ã«å¯Ÿãã远å ã®çµã¿èŸŒã¿é¢æ°
FSharp.Core 6.0.0 ã§ã¯ã NativePtr ã¢ãžã¥ãŒã«ã«æ°ããçµã¿èŸŒã¿ã远å ãããŸãã
NativePtr.nullPtrNativePtr.isNullPtrNativePtr.initBlockNativePtr.clearNativePtr.copyNativePtr.copyBlockNativePtr.ofILSigPtrNativePtr.toILSigPtr
NativePtrã®ä»ã®é¢æ°ãšåæ§ã«ããããã®é¢æ°ã¯ã€ã³ã©ã€ã³åããã/nowarn:9ã䜿çšãããªãéãããã®äœ¿çšã«ãã£ãŠèŠåãåºåãããŸãã ãããã®é¢æ°ã®äœ¿çšã¯ãã¢ã³ãããŒãžåã«å¶éãããŸãã
ãã®æ©èœã«ã€ããŠã¯ã F# RFC FS-1109 ãåç §ããŠãã ããã
åäœæ³šéãå«ã远å ã®æ°å€å
F# 6ã«ãããŠã以äžã®åãåçç¥å¥åããåäœã®æ³šéã«å¯Ÿå¿ããããã«ãªããŸããã æ°ãã远å ã¯å€ªåã§è¡šç€ºãããŸãã
| F# ãšã€ãªã¢ã¹ | CLR å |
|---|---|
float32/single |
System.Single |
float/double |
System.Double |
decimal |
System.Decimal |
sbyte/int8 |
System.SByte |
int16 |
System.Int16 |
int/int32 |
System.Int32 |
int64 |
System.Int64 |
byte/uint8 |
System.Byte |
uint16 |
System.UInt16 |
uint/uint32 |
System.UInt32 |
uint64 |
System.UIn64 |
nativeint |
System.IntPtr |
unativeint |
System.UIntPtr |
ããšãã°ã次ã®ããã«ç¬Šå·ãªãæŽæ°ã«æ³šéãä»ããããšãã§ããŸãã
[<Measure>]
type days
let better_age = 3u<days>
ãã®æ©èœã«ã€ããŠã¯ã F# RFC FS-1091 ã«èšèŒãããŠããŸãã
䜿çšé »åºŠã®äœãèšå·æŒç®åã«é¢ããæ å ±èŠå
F# 6 ã§ã¯ãF# 6 以éã§ :=ã !ã incrã decr ã®äœ¿çšãæ£èŠåè§£é€ãããœãã ã¬ã€ãã³ã¹ã远å ãããŠããŸãã ãããã®æŒç®åãšé¢æ°ã䜿çšãããšãã³ãŒãã Value ããããã£ã®æç€ºçãªäœ¿çšã«çœ®ãæããããšãæ±ããæ
å ±ã¡ãã»ãŒãžãçæãããŸãã
F# ããã°ã©ãã³ã°ã§ã¯ãåç
§ã»ã«ãããŒãå²ãåœãŠå€æŽå¯èœã¬ãžã¹ã¿ã«äœ¿çšã§ããŸãã ãããã¯æã
圹ã«ç«ã¡ãŸããã代ããã« let mutable ã䜿çšã§ãããããææ°ã® F# ã³ãŒãã£ã³ã°ã§ã¯ã»ãšãã©å¿
èŠãããŸããã F# ã³ã¢ ã©ã€ãã©ãªã«ã¯ã := ãš ! ã® 2 ã€ã®æŒç®åãšãåç
§åŒã³åºãã«ç¹ã«é¢é£ incr 2 ã€ã®é¢æ°ãš decr ãå«ãŸããŠããŸãã ãããã®æŒç®åãååšãããšãåç
§ã»ã«ã¯å¿
èŠä»¥äžã« F# ããã°ã©ãã³ã°ã®äžå¿ã«ãªãããã¹ãŠã® F# ããã°ã©ãã«ãããã®æŒç®åãç¥ãå¿
èŠããããŸãã ããã«ã ! æŒç®åã¯ãC# ããã®ä»ã®èšèªã§ã® not æäœãšç°¡åã«æ··åã§ããŸããããã¯ãã³ãŒãã翻蚳ããéã«ãæœåšçã«åŸ®åŠãªãã°ã®åå ãšãªãå¯èœæ§ããããŸãã
ãã®å€æŽã®æ ¹æ ã¯ãF# ããã°ã©ããç¥ãå¿ èŠãããæŒç®åã®æ°ãæžãããåå¿è åãã® F# ãç°¡ç¥åããããšã§ãã
ããšãã°ã次㮠F# 5 ã³ãŒããèããŠã¿ãŸãããã
let r = ref 0
let doSomething() =
printfn "doing something"
r := !r + 1
æåã«ãææ°ã® F# ã³ãŒãã£ã³ã°ã§ã¯åç
§ã»ã«ãå¿
èŠã«ãªãããšã¯ã»ãšãã©ãããŸããã let mutable ã¯é垞代ããã«äœ¿çšã§ããŸãã
let mutable r = 0
let doSomething() =
printfn "doing something"
r <- r + 1
åç
§ã»ã«ã䜿çšããå ŽåãF# 6 ã§ã¯ãæåŸã®è¡ã r.Value <- r.Value + 1ã«å€æŽããããæ±ããæ
å ±èŠåãåºåãããåç
§ã»ã«ã®é©åãªäœ¿çšã«é¢ãã詳现ãªã¬ã€ãã³ã¹ã«ãªã³ã¯ãããŸãã
let r = ref 0
let doSomething() =
printfn "doing something"
r.Value <- r.Value + 1
ãããã®ã¡ãã»ãŒãžã¯èŠåã§ã¯ãããŸããããããã¯ãIDE ãšã³ã³ãã€ã©ã®åºåã«è¡šç€ºããã "æ å ±ã¡ãã»ãŒãž" ã§ãã F# ã¯äžäœäºææ§ãç¶æããŸãã
ãã®æ©èœã¯ ãF# RFC FS-1111 ãå®è£ ããŸãã
Visual Studio ã§ã¹ã¯ãªããã§ã®æ¢å®ã .NET 6 ãšãªã F# ããŒã«
Visual Studio ã§ F# ã¹ã¯ãªãã (.fsx) ãéããå®è¡ããå Žåãæ¢å®ã§ã¯ãã¹ã¯ãªããã¯åæããã64 ãããå®è¡ã§ .NET 6 ã䜿çšããŠå®è¡ãããŸãã ãã®æ©èœã¯ãVisual Studio 2019 ã®ä»¥éã®ãªãªãŒã¹ã§ãã¬ãã¥ãŒæ®µéã«ãããæ¢å®ã§æå¹ã«ãªããŸããã
.NET Framework ã¹ã¯ãªãããæå¹ã«ããã«ã¯ã ããŒã«>ãªãã·ã§ã³>F# ããŒã«>F# 察話åãéžæããŸãã [.NET Core ã¹ã¯ãªããã®äœ¿çš] ãfalse ã«èšå®ããF# 察話åãŠã£ã³ããŠãåèµ·åããŸãã ãã®èšå®ã¯ãã¹ã¯ãªããã®ç·šéãšã¹ã¯ãªããã®å®è¡ã®äž¡æ¹ã«åœ±é¿ããŸãã .NET Framework ã¹ã¯ãªããã® 32 ãããå®è¡ãæå¹ã«ããã«ã¯ã 64 ããã F# Interactive ã false ã«èšå®ããŸãã .NET Core ã¹ã¯ãªããã«ã¯ 32 ããã ã®ãªãã·ã§ã³ã¯ãããŸããã
F# ããŒã«: F# ã¹ã¯ãªããã® SDK ããŒãžã§ã³ããã³çããã
.NET SDK èšå®ã®global.jsonãã¡ã€ã«ãå«ããã£ã¬ã¯ããªã§dotnet fsiã䜿çšããŠã¹ã¯ãªãããå®è¡ããå Žåã¯ãäžèŠ§è¡šç€ºãããŠããããŒãžã§ã³ã® .NET SDK ã䜿çšããŠã¹ã¯ãªãããå®è¡ããã³ç·šéããŸãã ãã®æ©èœã¯ãF# 5 ã®æ°ããããŒãžã§ã³ã§äœ¿çšã§ããŸãã
ããšãã°ã.NET SDK ããŒãžã§ã³ ããªã·ãŒãæå®ããæ¬¡ã® global.json ãã¡ã€ã«ãå«ãã¹ã¯ãªããããã£ã¬ã¯ããªå ã«ãããšããŸãã
{
"sdk": {
"version": "5.0.200",
"rollForward": "minor"
}
}
dotnet fsiã䜿çšããŠã¹ã¯ãªãããå®è¡ãããšããã®ãã£ã¬ã¯ããªãã SDK ã®ããŒãžã§ã³ãåªå
ãããŸãã ããã¯ãã¹ã¯ãªããã®ã³ã³ãã€ã«ãåæãå®è¡ã«äœ¿çšããã SDK ã "ããã¯ããŠã³" ã§ãã匷åãªæ©èœã§ãã
Visual Studio ããã®ä»ã® IDE ã§ã¹ã¯ãªãããéããŠç·šéãããšãã¹ã¯ãªããã®åæãšãã§ãã¯æã«ãã®èšå®ãããŒã«ã«ãã£ãŠèæ ®ãããŸãã SDK ãèŠã€ãããªãå Žåã¯ãéçºçšã³ã³ãã¥ãŒã¿ãŒã«ã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã
Linux ããã®ä»ã® Unix ã·ã¹ãã ã§ã¯ãããã shebang ãšçµã¿åãããŠãã¹ã¯ãªãããçŽæ¥å®è¡ããããã®èšèªããŒãžã§ã³ãæå®ã§ããŸãã
script.fsxã«ãããç°¡åãªã·ã§ãã³ã¯ããã§ãã
#!/usr/bin/env -S dotnet fsi
printfn "Hello, world"
script.fsxã䜿çšããŠã¹ã¯ãªãããçŽæ¥å®è¡ã§ããããã«ãªããŸããã ããããæ¬¡ã®ãããªç¹å®ã®æ¢å®ä»¥å€ã®èšèªããŒãžã§ã³ãšçµã¿åãããããšãã§ããŸãã
#!/usr/bin/env -S dotnet fsi --langversion:5.0
泚
ãã®èšå®ã¯ãææ°ã®èšèªããŒãžã§ã³ãæ³å®ããŠã¹ã¯ãªãããåæããç·šéããŒã«ã§ã¯ç¡èŠãããŸãã
åŸæ¥ã®æ©èœã®åé€
F# 2.0 以éãéæšå¥šã®ã¬ã¬ã·æ©èœã®äžã«ã¯ãé·ãéèŠåã衚瀺ãããŠãããã®ããããŸãã F# 6 ã§ãããã®æ©èœã䜿çšãããšã /langversion:5.0ãæç€ºçã«äœ¿çšããªãéãããšã©ãŒãçºçããŸãã ãšã©ãŒãçºçããæ©èœã¯æ¬¡ã®ãšããã§ãã
-
(int, int) Dictionaryãªã©ãåŸçœ®ååã䜿çšããè€æ°ã®ãžã§ããªã㯠ãã©ã¡ãŒã¿ãŒã ãã㯠F# 6 ã§ãšã©ãŒã«ãªããŸãã 代ããã«ãæšæºæ§æDictionary<int,int>ã䜿çšããå¿ èŠããããŸãã -
#indent "off"ã ããã¯ãšã©ãŒã«ãªããŸãã -
x.(expr)ã ããã¯ãšã©ãŒã«ãªããŸãã -
module M = struct ⊠endã ããã¯ãšã©ãŒã«ãªããŸãã - å
¥å
*.mlãš*.mliã®äœ¿çšã ããã¯ãšã©ãŒã«ãªããŸãã -
(*IF-CAML*)ãŸãã¯(*IF-OCAML*)ã®äœ¿çšã ããã¯ãšã©ãŒã«ãªããŸãã -
landãlorãlxorãlslãlsrããŸãã¯asrãã€ã³ãã£ãã¯ã¹æŒç®åãšããŠäœ¿çšããŸãã ããã㯠F# ã®ã€ã³ãã£ãã¯ã¹ ããŒã¯ãŒãã§ãããã㯠OCaml ã®ã€ã³ãã£ãã¯ã¹ ããŒã¯ãŒãã§ãããFSharp.Core ã§ã¯å®çŸ©ãããŠããªãããã§ãã ãããã®ããŒã¯ãŒãã䜿çšãããšãèŠåãåºåãããããã«ãªããŸããã
ããã«ããã F# RFC FS-1114 ãå®è£ ãããŸãã