2012-05-10 57 views
7

似乎Frege關於類型類別的想法與Haskell有很大不同。特別是:Frege類如何工作?

  • 的語法似乎是不同的,沒有明顯的理由。

  • 函數類型不能有類實例。 (看起來相當奇怪的規則......)

  • 語言規範說明了在子類實例聲明中實現超類的一些事情。 (但是,如果你有鑽石繼承...這不會是一個錯誤,但它不能保證以某種方式工作?)

  • 弗雷格是關於什麼樣的實例不那麼挑剔。 (類型別名是允許的,類型變量不需要是不同的,等等)

  • 方法可以聲明爲native,雖然它不完全清楚這是什麼意思。

  • 看來你可以寫type.method來訪問一個方法。再次,沒有跡象表明這意味着什麼或爲什麼它有用。

  • 子類聲明可以爲超類方法提供默認實現。 (?)

總之,如果有人知道這個東西可以寫一個關於這個東西是如何工作的解釋會很有用。它在語言規範中列出,但描述有點簡潔。 (關於語法:我認爲Haskell的實例語法更符合邏輯。「如果X是Y和Z的一個實例,那麼它也是Q的一個實例,如下所示......」Haskell的類語法總是看起來有點奇怪,如果X實現了Eq,那不是暗示它實現Ord,這意味着它可能可能實現Ord如果它想要的話,我不知道什麼是更好的符號。 ..)


每英戈的回答是:

  • 我假設提供一個超類方法的默認實現只適用於如果你聲明你的實例「一次全部」?

例如,假設FooBar的超類。假設每個類有三種方法(foo1,foo2,foo3,bar1,bar2,bar3),並且Bar提供了foo1的默認實現。這應該意味着

 
instance Bar FB where 
    foo2 = ... 
    foo3 = ... 
    bar1 = ... 
    bar2 = ... 
    bar3 = ... 

應該工作。但這樣做的工作:

 
instance Foo FB where 
    foo2 = ... 
    foo3 = ... 

instance Bar FB where 
    bar1 = ... 
    bar2 = ... 
    bar3 = ... 
  • 所以,如果我聲明瞭一個方法,在類聲明native,這只是設置默認實施該方法?

所以,如果我這樣做

 
class Foobar f where 
    foo :: f -> Int 
    native foo 

    bar :: f -> String 
    native bar 

那麼這只是意味着,如果我寫了一些Java本機類的空實例聲明,然後foo映射到object.foo()在Java中?

特別是,如果一個類的方法被聲明爲native,我仍然可以提供一些其他它的實現,如果我選擇?

  • 每種類型[構造函數]是一個名稱空間。我知道這將對臭名昭着的命名領域問題有所幫助。我不確定爲什麼你想要在這個命名空間範圍內聲明其他東西...

回答

6

你似乎已經仔細閱讀了語言規範。大。但是,不,類型類/實例與Haskell 2010沒有太大的區別。只是稍微一點,這一點是符號化的。

您的積分:

ad 1.是的。規則是約束(如果有)附加到類型上,並且類名稱遵循關鍵字。但是,當將多參數類型類添加到語言中時,這將很快改變爲支持Haskell語法。

ad 2.同時,完全支持函數類型。這將包含在下一個版本中。不過,目前的版本只支持(a-> b)。

ad 3.是的。考慮我們的分類類層次結構Functor - > Applicative - > Monad。你可以只寫下面的代替3個不同的實例:

instance Monad Foo where 
    -- implementation of all methods that are due Monad, Applicative, Functor 

ad 4.是的,目前。然而,多參數類型類將會有變化。 lang規範建議留在Haskell 2010規則中。

ad 5.如果您使用類型類對Java類層次結構進行建模,則需要這樣做。本地函數聲明對類型類/實例沒有什麼特別之處。因爲你可以在一個類中有一個註解和一個默認的實現(就像Haskell 2010中一樣),你可以用一個本地聲明的形式來表示它,它給出a)類型和b)實現(通過引用Java方法)。

ad 6.它的正交性。就像你可以寫M.foo,其中M是一個模塊一樣,當T是一個類型(構造函數)時,你可以寫T.foo,因爲兩者都是命名空間。此外,如果您有「記錄」,則當弗雷格無法推斷出x的類型時,您可能需要編寫T.f x

foo x = x.a + x.b -- this doesn't work, type of x is unknown 
-- remedy 1: provide a type signature 
foo :: Record -> Int -- Record being some data type 
-- remedy 2: access the field getter functions directly 
foo x = Record.a x + Record.b x 

ad 7.是的,例如,Ord在比較方面有(==)的默認實現。因此,您可以在不實現(==)的情況下創建一個Ord實例。

希望這會有所幫助。一般來說,必須說,lang規範需要a)完成和b)更新。如果只有一天了36小時.....

句法問題也這裏討論:https://groups.google.com/forum/?fromgroups#!topic/frege-programming-language/2mCNWMVg5eY

----第二部分------------

你的例子不起作用,因爲如果你定義了instance Foo FB那麼這個必須保持,不管其他實例和子類。 Bar中的默認foo1方法將僅在沒有Foo實例存在的情況下使用。

那麼這隻意味着如果我爲 某個Java本地類寫入空實例聲明,那麼foo會映射到Java中的object.foo()?

是的,但它取決於本地報關,它不必是Java類的Java實例方法,它也可能是一個靜態方法或其他類的方法,或只是一個成員訪問等

特別是,如果一個類方法被聲明爲本地,我仍然可以提供 一些其他實現,如果我選擇?

當然,就像其他任何默認的類方法一樣。假設默認的類方法是使用模式守衛來實現的,但這並不意味着您必須爲您的實現使用模式守衛。

看,

native [pure] foo "javaspec" :: a -> b -> c 

只是意味着:請讓我弗雷格功能foo A型 - 「乙 - 」ç碰巧使用javaspec實施。 (究竟如何,應該在語言參考的第6章,說明它尚未對不起。) 例如:

native pure int2long "(long)" :: Int -> Long 

編譯器會看到達這在語法上是一個轉換操作,而當它認爲:

... int2long val ... 

它會生成Java代碼,如:

((long)(unbox(val)) 

除此之外,它也會使包裝,這樣就可以,例如:

map int2long [1,2,4] 

的一點是,如果我告訴你:有一個函數X.Y.Z,你不能告訴這是否是本地或正一個不看源代碼。因此,native是將Java方法,運算符等提升到Frege領域的方法。幾乎所有在Haskell中被稱爲「primOp」的東西都只是Frege中的本地函數。例如,

pure native + :: Int -> Int -> Int 

(當然,這並不總是那麼容易。)

每個類型[構造函數]是一個名稱空間。我得到這將是 有助於臭名昭着的領域問題。我不知道你爲什麼要 要聲明在這個命名空間的範圍內的其他東西...

它給你更多的控制頂部名稱空間。除此之外,你不要必須在那裏定義其他的東西。一旦我承諾採用這種簡單的方法來解決記錄領域問題,我就沒有理由禁止它。

+0

我想澄清一些小問題。儘管如此,我不認爲他們會適合評論。所以我要編輯這個問題,而不是... – MathematicalOrchid

+0

@MathematicalOrchid - 當然沒問題。 – Ingo

+0

那麼我在哪裏可以幫助完成編寫規範? ;-) – MathematicalOrchid