'A ->' b tipi ML fonksiyonu


19

Profesörümüz bizden OCaml'de böyle bir işlevi düşünmemizi istedi

'a -> 'b

yani bir argümanın herhangi bir şey olabilen ve farklı bir şey döndürebilen bir işlevi.

raiseArgümanını göz ardı eden bir işlevde kullanmayı düşündüm :

let f x = raise Exit

Ancak profesör, standart kütüphanede herhangi bir işlev gerektirmeyen bir çözüm olduğunu söyledi. Kafam karıştı: 'bilk etapta yoksa nasıl yapabilirim ?

Burada Stack Overflow yerine soruyorum çünkü neler olup bittiğini anlamak istiyorum, sadece açıklamasız bir program görmek istemiyorum.


2
Lütfen cevabınızda CS101 öğrenci öğrenme programlamasını hedefleyin, cevabınızın daha sonra olmaları için ilham kaynağı olabileceği tür teorisyeni değil.
Gilles 'SO- kötü olmayı bırak

Bunun raiseişe yarayacağını nasıl anladığınızı açıklarsanız yardımcı olur , bu nedenle prof'inizin neden aradığı çözümü (en iyi çalışan aynı nedenlerle raiseçalışacaktır) açıklamanın en iyi nasıl açıklanacağını biliyoruz .
sepp2k

@ sepp2k Bu raise : exn -> 'ayüzden dönüş değerini alabilirim, sadece argümanı görmezden gelirim.
Gilles 'SO- kötü olmayı bırak


Yanıtlar:


18

İskelet let f x = BODY. VÜCUT olarak (örneğin, beklediği tamsayılar olduğu bir işleve göndermeyin) sadece jenerik şekillerde x kullanabilirsiniz gerekir ve değeri dönmelidir herhangi başka tip. Fakat ikinci kısım nasıl doğru olabilir? Deyimini karşılamak için tek yol "her türlü 'b, döndürülen değer türünde bir değerdir 'bemin fonksiyonu yok yapmaktır" değil dönün. Tam olarak iki olasılık vardır: VÜCUT hataları veya sona ermez. İşlev raisehata veriyor, aşağıdakiler sona ermiyor:

let rec f x = f x

19

İlk olarak, bazı açıklamalar. Sadece çekirdek tipli lambda hesabı kullanılarak 'a -> 'b, yazma sistemi sezgisel mantıklara ( Curry Howard izomorfizmi yoluyla ) karşılık geldiğinden ve karşılık gelen formül A → Bbir totoloji olmadığından elde etmek mümkün değildir.

Bu tür küpe ve eşleşmeleri gibi diğer uzantılar / şart hala mantıksal tutarlılık ilave ürün türleri korumak *mantıksal bağ karşılık gelen ve , ve toplam türleri |tekabül için veya . Yine, bu 'a -> 'btip üretmelerini beklemeyin , çünkü bir totoloji olmayan bir formülün kanıtlanmasına izin verecektir.

Yani tek şansınız mantıklardan kaçan diğer yapıları kullanmaktır raise(ancak bu durumda izin verilmez)… veya let rec! Özyineleme, hiçbir zaman sonlandırılmayacak programlar oluşturulmasına izin verir ve sonuçlarına, asla üretilmeyecekleri için rastgele bir dönüş türü verilebilir. Şimdi en önemsiz sonlandırma işlevini (bir sonucu döndürmek için doğrudan kendisini çağıran) düşünürseniz:

let rec f x = f x

Türünün tam olarak olduğunu fark edeceksiniz 'a -> 'b: sağlanan argüman ne olursa olsun, sonucun (asla hesaplanmayacak) herhangi bir türe sahip olduğu varsayılabilir.

Tabii ki bu filginç bir işlev değil, ama mesele bu. OCaml'de, türü geçerli bir formül gibi görünmeyen herhangi bir işlev şüpheli bir işlevdir.


Asker, ilk iki paragrafınızın tek bir kelimesini anlamadı, ama cümlenizi beğendim “sonuçlarına asla üretilmeyecekleri keyfi bir dönüş türü verilebilir”.
Gilles 'SO- kötü olmayı bırak'

1

İlkel bir derleyici kullanarak şunu yazabilirsiniz:

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

(ve aslında dilin bir parçası olmasa da derleyici dağıtımı bunu sağlar). Bu güvensiz bir kimlik.

Profesörünüz bunu kesinlikle istemiyor. Bununla birlikte, bu aynı zamanda farkında olduğum tipteki tek yararlı işlevdir 'a -> 'bve gerçekten de OCaml dağıtımının kendisinde kullanılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.