คุณมีเคล็ดลับทั่วไปเกี่ยวกับการเล่นกอล์ฟใน F # อย่างไร ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ F # (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คุณมีเคล็ดลับทั่วไปเกี่ยวกับการเล่นกอล์ฟใน F # อย่างไร ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ F # (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คำตอบ:
ใช้function
แทนmatch
เมื่อทำได้ มันจะบันทึก 6 ตัวอักษรสำหรับตัวแปร 1 ตัว:
let f=function // ... (14 chars)
VS
let f x=match x with // ... (20 chars)
นอกจากนี้ยังสามารถแทนที่การจับคู่รูปแบบใด ๆ เพื่อบันทึก 1 อักขระอย่างสม่ำเสมอ:
match a with| // ... (13 chars)
a|>function| // ... (12 chars)
(function| (* ... *))a // (12 chars)
จำเป็นต้องใช้วิธีการกับตัวแปรที่คุณยังไม่ได้ จำกัด ประเภทหรือไม่ เพียงเปรียบเทียบกับตัวอักษรประเภทที่คุณต้องการแล้วทิ้งผลลัพธ์เพื่อเพิ่มความคิดเห็นชนิดของตัวแปรนั้น:
let f (x:string)=x.Length
let f x=x="";x.Length
ใช้สัญลักษณ์นำหน้าสำหรับตัวดำเนินการมัดเมื่อคุณสามารถ - มันจะช่วยให้คุณไม่ต้องกำหนดฟังก์ชั่นที่จะใช้พวกเขา
ตัวอย่างเช่นคุณสามารถเปลี่ยนสิ่งนี้:
List.map(fun i->i+2)[1;1;2;3;5;8]
เป็นนี้
List.map((+)2)[1;1;2;3;5;8]
ในกรณีที่คุณไม่สามารถใช้ตัวแปรได้ให้ใช้ tuple deconstruction แทนการใช้ expression หลาย ๆ ตัว
let a,b ="",[]
แทน
let a=""
let b=[]
F # ห้องสมุดหลักกำหนดนามแฝงสำหรับเรียกว่าSystem.Console.In
stdin
สิ่งเหล่านี้ช่วยให้คุณอ่านอินพุต
// Signature:
stdin<'T> : TextReader
ข้อได้เปรียบที่ยิ่งใหญ่นอกเหนือจากความจริงที่ว่ามันสั้นกว่าConsole
คือคุณไม่จำเป็นต้องเปิดระบบเช่นกัน
string นั้นเป็นสิ่งchar seq
นี้ช่วยให้คุณใช้Seq.map
โดยตรงกับสตริง นอกจากนี้ยังเป็นไปได้ที่จะใช้พวกเขาในความเข้าใจ[for c in "" do]
การใช้เซลล์อ้างอิงจะไม่สั้นลงทุกครั้งเนื่องจากการอ่านทุกครั้งมาพร้อมกับอักขระเพิ่มเติมเพื่อทำลายเซลล์
เป็นไปได้ที่จะเขียนmatch .. with
แบบอินไลน์ที่สมบูรณ์
function|'a'->()|'b'->()|_->()
ไม่จำเป็นต้องมี white-space ก่อนและหลังอักขระที่ไม่ใช่ตัวอักษรและตัวเลข
String.replicate 42" "
if Seq.exists((<>)'@')s then
if(Seq.exists((<>)'@')s)then
ในกรณีที่คุณจำเป็นต้องใช้สตริงหรือช่องว่างด้านซ้ายหรือขวาคุณสามารถใช้ [s] printf [n] ค่าสถานะนั้น
> sprintf "%20s" "Hello, World!";;
val it : string = " Hello, World!"
id เป็นผู้ดำเนินการยืนฟังก์ชั่นตัวตน
let u x=x|>Seq.countBy (fun x->x)
สามารถเขียนได้
let u x=x|>Seq.countBy id
ฉันใช้ที่นี่
ขอบคุณมากที่Laikoniสำหรับเคล็ดลับนี้เป็นหนึ่งในการแก้ปัญหาของฉัน
พิจารณาฟังก์ชั่นพูดรวมสตริงด้วย 3 สำหรับตัวอักษรตัวพิมพ์ใหญ่และ 1 สำหรับอักขระอื่นทั้งหมด ดังนั้น:
let counter input = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1) input
โดยการแปลง etaนี้สามารถเขียนใหม่เป็น:
let counter = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)
และเรียกแบบเดียวกับเมื่อก่อน:
counter "Hello world!" |> printfn "%i"
>>
ตอนนี้สมมติว่าความท้าทายเริ่มแรกของเราคือการรวมสตริงด้วย 3 สำหรับตัวอักษรตัวพิมพ์ใหญ่และ 1 สำหรับตัวอักษรพิมพ์เล็กและอักขระอื่น ๆ ทั้งหมดจะไม่รวมอยู่ด้วย
เราอาจเขียนสิ่งนี้เป็น:
let counter input = Seq.filter Char.IsLetter input |> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)
เราสามารถใช้ตัวดำเนินการส่งต่อองค์ประกอบ ( >>
) เพื่อโยงทั้งสองฟังก์ชัน ( Seq.filter
และSeq.sumBy
) เข้าด้วยกัน ด้วยการแปลง eta นิยามฟังก์ชันจะกลายเป็น:
let counter = Seq.filter Char.IsLetter >> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)
คริสสมิ ธ ได้เขียนขึ้นมากใน>>
ผู้ประกอบการของเขาบล็อก MSDN
เมื่อเป็นไปได้Seq
จะสั้นกว่าList
:
[[1];[2;3];[4];[5]|>List.collect
[[1];[2;3];[4];[5]|>Seq.collect
หนึ่งตัวอักษรสั้นลง ...
let f = [(0,1);(1,4)]|>Seq.map(fst)
printfn "%A" f
สามารถเขียนได้
let f = [0,1;1,4]|>Seq.map fst
printfn "%A" f
สิ่งนี้จะเริ่มชำระด้วยอักขระบรรทัดใหม่หนึ่งบรรทัดในรหัสของคุณ กรณีใช้งานหนึ่งกรณีอาจเป็น:
string.Concat"\n"
string.Concat"
"
แรงบันดาลใจจากคำตอบ Chiru สำหรับ ES6
ใช้ที่นี่
.NET เสนอตัวบิวอินดี ๆ มากมาย F # สามารถใช้พวกเขาได้ดังนั้นอย่าลืมพวกเขา!
ตัวอย่าง:
open System.Linq
มันจะมีประโยชน์!
ใช้ lambdas เพื่อบันทึกไบต์ ตัวอย่างเช่นสิ่งนี้:
let f x=x*x
สามารถแสดงได้ดังนี้:
fun x->x*x
for i in[0..2]
for i=0 to 2
module
คำหลักที่สามารถนำมาใช้เพื่อตัดชื่อโมดูลเมื่อนำมาใช้ซ้ำแล้วซ้ำอีก ตัวอย่างเช่น:
Array.fold ...
Seq.iter ...
List.map ...
สามารถกลายเป็น
module A=Array
A.fold ...
module S=Seq
S.iter ...
module L=List
L.map ...
สิ่งนี้มีประโยชน์มากขึ้นสำหรับโปรแกรมที่ยาวกว่าที่ใช้วิธีการโมดูลซ้ำ ๆ (และต้องตั้งชื่อเต็มทุกครั้งเพราะมีRequireQualifiedAccess
ตัวปรับแต่ง) และอนุญาตให้โกนทิ้งได้สองสามตัวโดยเฉพาะเมื่อมีประโยชน์มากกว่าในการใช้อาร์เรย์ CLR ปกติ (เช่นความไม่แน่นอน ) กว่า F # หรือseq
list