การใช้รายการกับฟังก์ชันที่ป้อนเพื่อตรวจสอบซ้ำซาก

ฉันต้องการเขียนฟังก์ชันใน haskell ซึ่งกำหนดว่าฟังก์ชันบูลีน (ป้อนด้วย lambda-expression ใน ghci) เป็นฟังก์ชันซ้ำซากหรือไม่ อินพุตควรมีลักษณะดังนี้:

taut n (\[x..] -> ... == ...)

taut 3 (\[x,y,z] -> ((x||y)||z) == (x||(y||z)) )

ฉันได้สร้างชุดค่าผสมบูลีนที่เป็นไปได้ทั้งหมดแล้ว

combinations n = replicateM n [True,False] 

cmb n = concat (combinations n)

แต่ตอนนี้ฉันต้องการฟังก์ชันที่นำองค์ประกอบเหล่านี้ของรายการมาแทรกลงในตัวแปร n ในฟังก์ชันที่ป้อนเข้าไป

ขอบคุณล่วงหน้า :)


person rsng    schedule 11.12.2011    source แหล่งที่มา
comment
นี่ไม่ใช่การบ้านจริงๆ แต่เป็นงานพิเศษของโมดูลในมหาวิทยาลัย...เราทำได้ถ้าต้องการ แต่ก็ไม่จำเป็น - แต่ฉันอยากทำ เพราะอย่างน้อยฉันก็อยากเข้าใจฮาสเคลบ้าง...   -  person rsng    schedule 11.12.2011


คำตอบ (1)


ฟังก์ชัน combinations ของคุณได้สร้างรายการความยาว n ที่มีการเรียงสับเปลี่ยนที่เป็นไปได้ทั้งหมดเป็น True และ False แล้ว คุณ ไม่ จำเป็นต้องใช้ concat; ผลลัพธ์ที่ได้รวมรายการที่เป็นไปได้ทั้งหมดไปยังฟังก์ชันของคุณแล้ว เป็นกรณีนี้เนื่องจากฟังก์ชันที่คุณกำลังตรวจสอบคาดว่าจะมีรายการอยู่แล้ว (อยู่ในรูปแบบ \[a,b,c...])

นั่นคือ สำหรับ fn การรับรายการความยาว 3 combinations 3 จะเป็น:

[[True,True,True],[True,True,False],[True,False,True],[True,False,False],
 [False,True,True],[False,True,False],[False,False,True],[False,False,False]]

แต่ละองค์ประกอบของรายการนี้คือ รายการ; คุณสามารถส่งผ่านไปยังฟังก์ชันที่คุณกำลังตรวจสอบ (อันที่อาจเป็นเรื่องซ้ำซาก) ได้โดยตรง จากรายการข้างต้น สิ่งที่คุณต้องทำคือลองใช้แต่ละองค์ประกอบ

แก้ไข (พยายามชี้แจงเล็กน้อย):

คุณต้องการฟังก์ชัน taut ที่รับฟังก์ชัน อีก ประเภท [Bool] -> Bool และกำหนดว่าฟังก์ชันนั้นเป็นฟังก์ชันซ้ำซ้อนหรือไม่ ซึ่งหมายความว่า taut จะมีประเภทเช่น Int -> ([Bool] -> Bool) -> Bool สมมติว่าคุณเริ่มต้นเช่นนี้:

taut :: Int -> ([Bool] -> Bool) -> Bool
taut n fn = ...

ตอนนี้ n คือความยาว และ fn คือฟังก์ชัน ฟังก์ชัน combinations ของคุณรับ n และส่งคืน อินพุต ที่ถูกต้องทุกรายการที่เป็นไปได้เป็น fn โปรดทราบว่า fn คาดหวัง [Bool] และ combinations n ก็คือ [[Bool]] ซึ่งหมายความว่าแต่ละองค์ประกอบสามารถเป็นอินพุตของ fn ได้ เมื่อรู้สิ่งนี้แล้ว สิ่งที่คุณต้องทำคือใช้ fn กับแต่ละองค์ประกอบของ combinations n และดูว่าผลลัพธ์จะเหมือนเดิมหรือไม่

ในฟังก์ชัน taut ของคุณ คุณไม่ต้องกังวลว่าตัวแปรภายในฟังก์ชันที่กำลังทดสอบจะได้รับมอบหมายอย่างไร เมื่อคุณเขียนฟังก์ชันนั้นจริงๆ ถ้ามันอยู่ในรูปของ \[x,y,z]->..., x, y และ z จะถูกกำหนดให้อยู่ภายในฟังก์ชันนั้นด้วยการจับคู่รูปแบบ

person Tikhon Jelvis    schedule 11.12.2011
comment
ใช่ ฉันสงสัยอยู่แล้วว่าจำเป็นต้องรวมพวกมันไว้ในรายการเดียวหรือไม่ แต่ฉันคิดว่าบางทีฉันอาจใช้รายการนี้และนับจำนวนและแทรกค่าบูลีนลงในตัวแปร...แต่นั่นคือจุดเริ่มต้นของปัญหาจริงๆ - ฉันคิดว่าฉันอาจเริ่มทดสอบว่าฉันสามารถป้อนฟังก์ชันแลมบ์ดาลงในโค้ดได้อย่างไร ดังนั้นฉันจึงพิมพ์ taut [x,y,z] = (\[x,y,z] -> ((x||y)||z) == (x||(y||z)) ) เพื่อดูว่าฉันสามารถแทรกค่าบูลีนสำหรับ x,y,z ได้หรือไม่ แต่ถึงอย่างนั้นฉันก็ไม่มีอินสแตนซ์ .. จากการใช้งาน ของข้อผิดพลาด 'การพิมพ์' ซึ่งฉันไม่เข้าใจจริงๆ ... - person rsng; 11.12.2011
comment
ฉันสับสนเล็กน้อยว่าคุณคาดหวังว่าฟังก์ชัน taut จะทำงานอย่างไร ฉันคิดว่าคุณต้องการให้มันใช้แลมบ์ดาและลองอินพุตทุกชุด คุณกำลังคิดที่จะทำอย่างอื่นหรือไม่? นอกจากนี้ taut ในความคิดเห็นของคุณดูเหมือนแตกต่างอย่างสิ้นเชิงกับ taut ในคำถามของคุณ โดยอันแรกใช้ตัวเลขและฟังก์ชัน อันที่สองดูเหมือนจะมีสองรายการ (Int -› [Bool] -› Bool vs [Bool] -› [Bool] -› Bool) - person Tikhon Jelvis; 11.12.2011
comment
ประโยคที่สองคือวิธีที่ฉันต้องการให้มันทำงานอย่างแน่นอน...ฟังก์ชันที่ตึงของฉันในความคิดเห็นด้านบนเป็นเพียงการทดสอบที่ฉันสามารถดูได้ว่าฉันสามารถแทรกค่าเพื่อเข้าใกล้วิธีแก้ปัญหาได้อย่างไร - แต่เห็นได้ชัดว่ามันใช้งานไม่ได้ ยังไงซะและฉันสงสัยว่า Haskell ก็ทำงานแบบนี้เหมือนกัน - person rsng; 11.12.2011
comment
ขวา. ฉันจะพยายามชี้แจงคำตอบของฉัน - person Tikhon Jelvis; 11.12.2011
comment
โอ้ และเกี่ยวกับ no instance ของคุณ... ข้อผิดพลาด: คุณอาจได้รับมันโดยการพิมพ์ค่าที่เป็นฟังก์ชัน มันแค่หมายความว่า ghci ไม่รู้วิธีพิมพ์ค่าที่คุณให้มา และมันไม่รู้ว่าจะเปลี่ยนฟังก์ชันให้เป็นสตริงได้อย่างไร - person Tikhon Jelvis; 11.12.2011
comment
นั่นช่วยได้มากจริงๆ...ฉันยังรู้วิธีใช้อาร์กิวเมนต์ของฟังก์ชันในพารามิเตอร์ด้วยการจำคณิตศาสตร์พื้นฐานของฉันก่อนที่จะเห็นคำตอบของคุณ...ฉันคิดว่าตอนนี้ฉันใกล้จะถึงวิธีแก้ปัญหาจริงแล้วแล้ว เมื่อฉันใช้ รายการบูลีนในฟังก์ชันตึงของฉันด้วย taut n fx = map fx(combinations n) - ตอนนี้ฉันได้รับรายการ [True,True..] และตอนนี้ฉันกำลังหาวิธีรวมสิ่งเหล่านั้นเข้ากับ 1 เอาต์พุตเดี่ยวหากทั้งหมดเป็นจริง - person rsng; 11.12.2011
comment
และเสร็จสิ้นแล้ว - taut n fx = and(map fx(combinations n)) ทำงานได้อย่างสมบูรณ์แบบ เมื่อมองย้อนกลับไป ทุกอย่างดูง่ายมาก :/ ฉันซาบซึ้งมากสำหรับความช่วยเหลือของคุณ ฉันคิดว่ามันทำให้ฉันก้าวไกลขึ้นมากในการคิดว่าฉันกำลังทำอะไรอยู่ - person rsng; 11.12.2011
comment
ดีใจที่ได้ยินว่าคุณได้ผล เป้าหมายของฉันคือการชี้แจงให้ชัดเจนเพียงพอเพื่อให้คุณได้รับคำตอบด้วยตัวเองโดยไม่ต้องเปิดเผย มันจะง่ายขึ้นเมื่อคุณเขียนโปรแกรมหลายๆ โปรแกรมใน Haskell แล้ว หมายเหตุเกี่ยวกับสไตล์: คุณสามารถแทนที่วงเล็บด้วย . และ $ ได้ ดังนั้นคุณจึงสามารถมี taut n fx = and . map fn $ combinations n ซึ่งอ่านง่ายกว่านิดหน่อย (ในความคิดของฉัน) - person Tikhon Jelvis; 11.12.2011