2016-02-12 134 views
1

爲了更好地理解Haskell,我想使用sum類型來構建一些遞歸列表結構。使用Haskell sum類型進行遞歸列表 - 遞歸錨?

這兩種類型是不相關的,但在同一個文件:

​​

所以我得到一個錯誤「‘空’的多次聲明」。閱讀this後,我知道'空'不是一個關鍵字(正如我在這個數據類型在課堂上呈現時所假定的那樣)。

如果我想在我的程序中使用n這樣的類型,我必須爲空元素提出n個不同的名稱,這看起來不正確。

是否有一個共同的表達式來確定列表的結尾? 或者我應該不使用這種'自制'類型?

+0

你爲什麼不直接叫第一個'Empty' - 'Nil'和第二個'Leaf'?那麼它會'感覺不錯'。但最終你必須 - 做到這一點 - 否則'空'可以用來構建樹或列表 - 也許一些LANGUAGE擴展可以幫助你 - 我想'AllowAmbiguousTypes',但我不知道。 – epsilonhalbe

+5

另一個選擇是 - 因爲它們不相關 - 創建兩個模塊 - MyList和MyTree - 然後,因爲命名空間是每個模塊,問題就解決了,如果您在一個文件中同時使用了兩個模塊,則必須執行限定的導入。看一看['containers'](https://hackage.haskell.org/package/containers)包,看看整齊排列的示例。 – epsilonhalbe

回答

2

假設您已被允許使用Empty構造函數聲明兩個數據類型,就像您所做的那樣。鑑於定義

x = Empty 

什麼是x的類型?它可能是EListETree,但電腦無法知道你的意思。這就是爲什麼一般來說,你不能在給定文件中多次聲明相同名稱的原因。

一個簡單的解決方案就是簡單地使用不同的名稱。在這裏,我使用Nil作爲空白列表,Leaf作爲空白樹。

data List = Cons Point List | Nil 
data Tree = Node Int Tree Tree | Leaf 

(旁白:它通常不申報的總和類型記錄的字段是個好主意,因爲這意味着提取將部分功能。)

另一種方法是把你的兩個重疊的名字在不同的文件。

List.hs:

module List where 
data List = Cons Point List | Empty 

Tree.hs:

module Tree where 
data Tree = Node Int Tree Tree | Empty 

現在,如果導入這兩個模塊,指的是Empty不允許的,因爲再一次機器不知道哪一個你的意思。但是這一次,你可以使用合格的名字自行排序。

import List 
import Tree 

emptyList = List.Empty 
emptyTree = Tree.Empty 
+0

這是一個正確的答案,但我不禁要指出,如果語言需要像這樣的含糊定義的類型聲明,那麼計算機將能夠處理'x = Empty'定義。 Haskell已經爲數字文字做了這個。所以這是一種語言規定的規則,而不是一些自然規律。 –

+0

@LuisCasillas我同意,事實上有些語言比Haskell更加靈活地處理不同類型的重疊名稱; Haskell選擇優先化類型推斷。儘管如此,數字文字並不是完全相同的東西;它們是多態的,具有'Num n => n'類型,所以類型是使用Haskell的常規實例選擇規則選擇的。 –