ฟังก์ชัน ML ของประเภท 'a ->' b


19

อาจารย์ของเราขอให้เราคิดถึงฟังก์ชั่นใน OCaml ที่มีรูปแบบ

'a -> 'b

เช่นฟังก์ชั่นของอาร์กิวเมนต์หนึ่งตัวที่อาจเป็นอะไรก็ได้และสามารถคืนสิ่งที่แตกต่างออกไปได้

ฉันคิดว่าจะใช้raiseในฟังก์ชั่นที่ไม่สนใจอาร์กิวเมนต์:

let f x = raise Exit

แต่อาจารย์กล่าวว่ามีวิธีแก้ปัญหาที่ไม่ต้องการฟังก์ชันใด ๆ ในไลบรารีมาตรฐาน ฉันสับสน: คุณจะสร้างได้'bอย่างไรถ้าคุณไม่มีในตอนแรก

ฉันถามที่นี่มากกว่า Stack Overflow เพราะฉันต้องการที่จะเข้าใจสิ่งที่เกิดขึ้นฉันไม่ต้องการเพียงแค่เห็นโปรแกรมที่ไม่มีคำอธิบาย


2
โปรดกำหนดเป้าหมายการเขียนโปรแกรมการเรียนรู้ของนักเรียน CS101 ในคำตอบของคุณไม่ใช่นักทฤษฎีประเภทที่คำตอบของคุณอาจเป็นแรงบันดาลใจให้เขากลายเป็นในภายหลัง
Gilles 'หยุดความชั่วร้าย'

มันจะช่วยถ้าคุณอธิบายว่าคุณคิดได้อย่างไรว่าraiseจะได้ผลเราจึงรู้วิธีที่ดีที่สุดที่จะอธิบายว่าเหตุใดโซลูชันของคุณจึงมองหา (ซึ่งจะทำงานได้ด้วยเหตุผลเดียวกันกับที่raiseทำงาน)
sepp2k

@ sepp2k raise : exn -> 'aดังนั้นฉันจะได้รับผลตอบแทนที่ฉันไม่สนใจอาร์กิวเมนต์
Gilles 'SO- หยุดความชั่วร้าย'


2
ดูเพิ่มเติมเหตุใดอัลกอริทึม Hindley-Milner จะไม่ให้ผลเช่น t1 -> t2 พูดคุยเกี่ยวกับการตั้งค่าทางทฤษฎีมากขึ้น
Gilles 'หยุดความชั่วร้าย'

คำตอบ:


18

let f x = BODYโครงกระดูกเป็น ในร่างกายของคุณต้องใช้ x เฉพาะในรูปแบบทั่วไป (เช่นไม่ส่งไปที่ฟังก์ชั่นที่คาดว่าจำนวนเต็ม) และคุณจะต้องกลับค่าใด ๆชนิดอื่น แต่ส่วนหลังจะเป็นจริงได้อย่างไร? วิธีเดียวที่จะทำให้เป็นไปตามคำสั่ง "สำหรับทุกประเภท'bค่าที่ส่งคืนคือค่าของประเภท'b" คือเพื่อให้แน่ใจว่าฟังก์ชันจะไม่ส่งคืน มีความเป็นไปได้สองประการ: ข้อผิดพลาดของร่างกายหรือไม่สิ้นสุด raiseความผิดพลาดของฟังก์ชั่นต่อไปนี้ไม่สิ้นสุด:

let rec f x = f x

19

ครั้งแรกข้อสังเกตบางอย่าง การใช้แคลคูลัสแลมบ์ดาที่พิมพ์ออกมาเป็นหลักนั้นเป็นไปไม่ได้ที่จะได้รับ'a -> 'bเพราะระบบการพิมพ์นั้นอยู่ในรูปแบบของจดหมายโต้ตอบ (ผ่านCurry Howard isomorphism ) ไปยัง intuitionistic logics และสูตรที่เกี่ยวข้องA → Bไม่ใช่เรื่องซ้ำซาก

นามสกุลอื่น ๆ เช่น tuples และจ้อ / เงื่อนไขยังคงรักษาความสอดคล้องตรรกะบางเพิ่มประเภทของสินค้า*ที่ตรงกับตัวดำเนินการตรรกะและและประเภทรวม|ซึ่งสอดคล้องกับหรือ อย่าคาดหวังว่าพวกเขาจะสร้าง'a -> 'bมันขึ้นมาเพราะมันจะช่วยให้ใครคนหนึ่งสามารถพิสูจน์สูตรบางอย่างที่ไม่ใช่การพูดซ้ำซาก

ดังนั้นโอกาสเดียวของคุณคือการใช้สิ่งก่อสร้างอื่น ๆ ที่หลบหนีจาก logics เช่นraise(แต่คุณไม่ได้รับอนุญาตในกรณีนี้) ... หรือlet rec! การเรียกซ้ำช่วยให้สามารถสร้างโปรแกรมที่ไม่สิ้นสุดและผลลัพธ์ของพวกเขาจะได้รับประเภทการส่งคืนตามอำเภอใจเนื่องจากจะไม่มีการผลิตซ้ำ ตอนนี้ถ้าคุณนึกถึงฟังก์ชั่นที่ไม่หยุดยั้งที่สุด (ฟังก์ชั่นที่เรียกตัวเองโดยตรงว่าให้ส่งคืนผลลัพธ์):

let rec f x = f x

คุณจะสังเกตได้ว่าประเภทของมันคือ'a -> 'bอะไร: อะไรก็ตามที่เป็นอาร์กิวเมนต์ที่ให้ไว้ผลลัพธ์ (ซึ่งจะไม่ถูกคำนวณ) สามารถสันนิษฐานได้ว่ามีประเภทใด

แน่นอนว่านี่fไม่ใช่ฟังก์ชั่นที่น่าสนใจ แต่นั่นคือประเด็น ใน OCaml ฟังก์ชันใด ๆ ที่มีประเภทไม่เหมือนสูตรที่ถูกต้องเป็นฟังก์ชันที่น่าสงสัย


ผู้ถามไม่เข้าใจคำสองย่อหน้าแรกของคุณ แต่ฉันชอบประโยคของคุณ“ ผลลัพธ์ของพวกเขาจะได้รับผลตอบแทนตามอำเภอใจเพราะพวกเขาจะไม่ทำ”
Gilles 'SO- หยุดความชั่วร้าย'

1

การใช้คอมไพเลอร์ดั้งเดิมคุณสามารถเขียนสิ่งนี้:

external magic: 'a -> 'b = "%identity"

(และแน่นอนการกระจายคอมไพเลอร์ให้สิ่งนี้แม้ว่าจะไม่ได้เป็นส่วนหนึ่งของภาษา) นี่เป็นตัวตนที่ไม่ปลอดภัย

อาจารย์ของคุณไม่ต้องการสิ่งนี้แน่นอน อย่างไรก็ตามนี่เป็นฟังก์ชั่นที่มีประโยชน์อย่างเดียวกับประเภท'a -> 'bที่ฉันรับรู้และแน่นอนมันถูกใช้ในการกระจาย OCaml เอง

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