เมื่อเร็ว ๆ นี้ฉันได้พบกับสถานการณ์ที่ฉันต้องการส่งผ่านฟังก์ชันเพรดิเคตไปยังฟังก์ชั่นอื่นและบ่อยครั้งที่ตรรกะที่ฉันกำลังค้นหาคือ "ค่านี้ตรงกับรูปแบบนี้หรือไม่"
การจับคู่รูปแบบดูเหมือนจะเป็นที่ต้องการในการประกาศdo
บล็อกและรายการความเข้าใจ แต่มีฟังก์ชันจำนวนมากที่ใช้คำกริยาa -> Bool
ซึ่งเป็นประโยชน์อย่างมากหากผ่านไปในรูปแบบ ตัวอย่างเช่นtakeWhile
, until
, find
, span
ฯลฯ
จนถึงขณะนี้ฉันได้ทำ\a -> case a of MyCons _ -> True; otherwise -> False
หรือเขียนฟังก์ชั่นที่มีชื่อ la let myPred (MyCons _) = True; myPred _ = False in
แต่พวกเขาทั้งสองดูเหมือนน่าเกลียดชะมัดและไม่สำนวนมาก วิธี "ชัดเจน" (และผิด) จะเป็นสิ่งที่ชอบ\(MyCons _) -> True
แต่นั่นทำให้เกิดข้อผิดพลาดในการเป็นบางส่วนโดยธรรมชาติและถึงแม้จะรู้สึกว่าต้องมีวิธีที่สะอาดกว่า
มีวิธีรวบรัด / สะอาดกว่านี้ในการทำสิ่งนี้หรือไม่? หรือฉันจะทำสิ่งต่าง ๆ โดยสิ้นเชิงผิด?
let myPred...
สไตล์ไม่ดีแต่มันให้ความรู้สึกละเอียดมากกว่าที่ฉันคาดไว้สำหรับความคิดที่ง่ายมากซึ่งทำให้ฉันสงสัยว่าฉันเห่าต้นไม้ผิดไปหรือเปล่า
maybe :: b -> (a -> b) -> Maybe a -> b
และbool :: a -> a -> Bool -> a
จากนั้นใช้กับฟังก์ชันบูลีนที่สร้างเป็นอาร์กิวเมนต์ เช่นนั้นเรียกmyCons z f (MyCons x) = f x ; myCons z f _ = z
myCons False (const True) aMyConsValue
นี่คือสิ่งที่คุณเขียนเกือบจะมีเพียง "ระดับทางอ้อม" / "นามธรรม" อีกระดับหนึ่งผ่านการโต้แย้งเชิงฟังก์ชันอบเข้ามา
let
ประโยคที่คุณไม่ชอบ - แม้ว่าฉันจะชอบwhere
ประโยคที่เทียบเท่ากัน แน่นอนว่าถ้าคุณต้องการยูทิลิตี้นี้มากกว่าหนึ่งครั้งคุณจะต้องกำหนดให้เป็นฟังก์ชันระดับบนสุด