2014-09-25 25 views

回答

6

data Binary = 0 | 1是不正常的定義數據類型的形式。 data定義需要數據構造函數01對於它們來說不是合法語法,因爲它們已經用於數字文字。這是第二條錯誤消息試圖告訴你的,並且是基本的Haskell。對於數據構造最常見的語法是一個大寫的話,那麼你可能想要的東西更像

data Binary = Zero | One 

注意:此消息的其餘部分是先進的東西,你可能不需要,但我覺得解釋關於你爲什麼得到第一個關於-XDataKinds的錯誤消息。

隨着DataKinds延伸,01做了別樣的成爲合法的「類型」(被稱爲Nat,而事實上「厚道」是這裏的技術術語),用於高級型級別的編程,並與還有幾個擴展它可能獲得包含它們的數據定義。

請注意,下面的例子可能不是真的有用,我只是拼湊在一起,以顯示它是可能的。在實踐中,除非你在做相當先進的東西,data Binary = Zero | One可能更像你想要的。

{-# LANGUAGE DataKinds, KindSignatures #-} 

import GHC.TypeLits (Nat) 

data Proxy (n :: Nat) = Proxy 
data WeirdBinary = Zero (Proxy 0) | One (Proxy 1) 

我還沒有真正能夠使工作(雖然我只嘗試了一會兒)是什麼,開始data Binary = 0。我得到的最接近像

class (n :: Nat) /// a where 

data Binary = (0 /// Bool) => ThisIsSilly 

奇怪的東西,其中0仍需要在括號內。我想邏輯上這種特殊的形式應該沒有括號的工作,但它不。

鑑於此,我認爲Haskell正在被不必要地混淆,因爲暗示有一些方法可以使擴展符合0。然而,使用分析和類型/類型檢查的方式在GHC中是分開的階段,以更加用戶友好的方式來捕捉它可能過於複雜,甚至最終可能意味着未來有效。

10

基本上,您不允許使用數字0和1作爲用戶定義類型的數據構造函數的名稱。在句法上,它們必須是以大寫字母開頭的單詞。例如,你可以這樣做,而不是:

data Binary = O | I 

(請注意,這些都是大寫字母「O」和「我」,而不是數字零和一。)

3

第一個錯誤是說,像01(或實際上"foo"[1, 2, 3]'Z')文字值是無效的類型聲明在所有

您無法聲明包含現有類型元素的新類型,因爲它看起來像您正在嘗試使用data Binday = 0 | 1。類型只能包含所有另一種類型的成員(這就是爲什麼你包括其他類型的類型表達式,不)。

DataKinds擴展引入了新的表單類型(我不會在這裏介紹),這意味着文字值可以出現在某些位置的類型聲明中。所以它確實解決了「非法文字類型」錯誤,但即使與DataKinds文字值仍不允許在位置。

第二個錯誤是告訴你編譯器無法解析「0」作爲構造函數名稱。施工人員必須以大寫字母開頭,其中0顯然沒有。

我之前撒謊時說過「類型只能包含所有的其他類型的成員」。實際上,新類型不能包含任何現有類型的成員;它們包含不屬於任何現有類型的全新值。這是通過要求所有新類型的值由構造函數來標記的;在data聲明中聲明瞭可能的構造函數,並且這是在寫入01的地方必須找到構造函數的地方。

0已經是現有的類型Int 的一員,所以它永遠是你的新類型Binary的成員,無論你如何申報。

你可以得到一個0這是包含在Binary類型的值ConstructorName 0,也許。但是,您將不得不聲明Binary類型爲data Binary = ConstructorName Int | ...;在類型聲明中的構造函數名稱後面應該有類型,用於標識可以放置在新的Binary值的「插槽」中的值的類型。還有沒有辦法使該「槽」只能包含01,它必須是一個整個類型。


或爲中綴運營商構造一個冒號,但在這裏,這是不相關的。

實際上文字表達0過載,因此它可能是代表任何數字類型的零元素,但我說的是一個是Int之一。