เคล็ดลับการตีกอล์ฟใน F #


21

คุณมีเคล็ดลับทั่วไปเกี่ยวกับการเล่นกอล์ฟใน F # อย่างไร ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ F # (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ

คำตอบ:


9

ใช้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)

8

จำเป็นต้องใช้วิธีการกับตัวแปรที่คุณยังไม่ได้ จำกัด ประเภทหรือไม่ เพียงเปรียบเทียบกับตัวอักษรประเภทที่คุณต้องการแล้วทิ้งผลลัพธ์เพื่อเพิ่มความคิดเห็นชนิดของตัวแปรนั้น:

let f (x:string)=x.Length
let f x=x="";x.Length

7

ใช้สัญลักษณ์นำหน้าสำหรับตัวดำเนินการมัดเมื่อคุณสามารถ - มันจะช่วยให้คุณไม่ต้องกำหนดฟังก์ชั่นที่จะใช้พวกเขา

ตัวอย่างเช่นคุณสามารถเปลี่ยนสิ่งนี้:

List.map(fun i->i+2)[1;1;2;3;5;8]

เป็นนี้

List.map((+)2)[1;1;2;3;5;8]

1
ฉันใช้ที่นี่ขอบคุณ!
aloisdg พูดว่า Reinstate Monica

5

การรื้อโครงสร้าง Tuple

ในกรณีที่คุณไม่สามารถใช้ตัวแปรได้ให้ใช้ tuple deconstruction แทนการใช้ expression หลาย ๆ ตัว

let a,b ="",[]

แทน

let a=""
let b=[]

อ่านจาก stdin

F # ห้องสมุดหลักกำหนดนามแฝงสำหรับเรียกว่าSystem.Console.In stdinสิ่งเหล่านี้ช่วยให้คุณอ่านอินพุต

// Signature:
stdin<'T> :  TextReader

TextReader บน msdn

ข้อได้เปรียบที่ยิ่งใหญ่นอกเหนือจากความจริงที่ว่ามันสั้นกว่า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!"
    

    โมดูล Core.Printf



3

การแปลง ETA สำหรับฟังก์ชั่น

ขอบคุณมากที่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


2

เมื่อเป็นไปได้Seqจะสั้นกว่าList:

[[1];[2;3];[4];[5]|>List.collect
[[1];[2;3];[4];[5]|>Seq.collect

หนึ่งตัวอักษรสั้นลง ...


2

หลีกเลี่ยงวงเล็บเมื่อใช้หนึ่งพารามิเตอร์และใน tuple

let f = [(0,1);(1,4)]|>Seq.map(fst)
printfn "%A" f

สามารถเขียนได้

let f = [0,1;1,4]|>Seq.map fst
printfn "%A" f

1
คุณไม่จำเป็นต้อง () รอบสิ่งอันดับ: let f = [0,1; 1,4] |> Seq.map fst
thinkbeforecoding

1
ขอขอบคุณ. อัปเดต
aloisdg พูดว่า Reinstate Monica

2

ต้องการสตริงบรรทัดใหม่ทับ "\ n"

สิ่งนี้จะเริ่มชำระด้วยอักขระบรรทัดใหม่หนึ่งบรรทัดในรหัสของคุณ กรณีใช้งานหนึ่งกรณีอาจเป็น:

(18 ไบต์)

string.Concat"\n"

(17 ไบต์)

string.Concat"
"

แรงบันดาลใจจากคำตอบ Chiru สำหรับ ES6

ใช้ที่นี่


1

ใช้. NET

.NET เสนอตัวบิวอินดี ๆ มากมาย F # สามารถใช้พวกเขาได้ดังนั้นอย่าลืมพวกเขา!

ตัวอย่าง:

open System.Linq

มันจะมีประโยชน์!


1

ใช้ lambdas เพื่อบันทึกไบต์ ตัวอย่างเช่นสิ่งนี้:

let f x=x*x

สามารถแสดงได้ดังนี้:

fun x->x*x


1

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 # หรือseqlist

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.