2015-05-01 75 views
0

我是Haskell的新成員。 我遇到了一個錯誤。代碼有點複雜,但我意識到它可以簡化如下。內容定義中的類型不匹配錯誤

import Data.Set (Set) 
import qualified Data.Set as S 

oA :: S.Set String 
oA = S.empty 

main::IO() 
main = do 
    let oA = S.fromList["a1","a2","a3","a4","a5"] 
    print [ a | a <- oA ] 
    return() 

這給了我一個錯誤,如下所示。

Module.hs:10:22: 
    Couldn't match expected type `[t0]' with actual type `Set [Char]' 
    In the expression: oA 
    In a stmt of a list comprehension: a <- oA 
    In the first argument of `print', namely `[a | a <- oA]' 

我該如何解決問題? 從其他編程語言(如java)的意義上來說, [ Set [Char] a | a <- oA ]可能會工作,但Haskell編譯器不接受此項。

+1

問題是,在這一點上你不需要Set:'let oA = [「a1」,...]'然後'[a |一個< - oA]'將起作用 - 如果我猜測你正在努力達到的目標,我可以嘗試進一步幫助你 – Carsten

+0

在你的常用列表中理解,'oA'也需要成​​爲一個列表,但是你做到了成爲一個錯誤發生的地方 – Carsten

+0

有一個擴展使它與[monads too]一起工作(https://ghc.haskell.org/trac/ghc/wiki/MonadComprehensions),但是'Set'沒有monad (又一個小問題)... – Carsten

回答

1

正如評論指出的那樣,問題是列表理解中的事物必須是列表。你試圖使用一個集合,這不是一個列表。 (雖然技術上是monad,但由於技術上的困難,你不能定義Haskell's的語法, Set類型的單子,但這是另一個討論。)

解決您的評論:「我不明白,Set和List之間的差別」 ......

首先,認識到計算機編程語言不喜歡數學。他們可能會使用從數學中借用的術語,但他們可能會用它來表示瘋狂的與您所期望的不同。在任何時候,你都必須在腦海中分離一組數據的數學定義,以及Haskell提供的面向機器的數據類型。

在這種特殊情況下,我們有列表類型[x]和集合類型Set x

  • Set x是一種數據結構,很不客氣地實現了,你會從數學組的期望。它存儲項目,並且您可以檢查設置的成員身份,這在機器級別上很有效。爲了實現這個,x需要擁有一個總的順序。 (集被實現爲查找樹。)

  • [x]更像值的數學序列。與Set不同,對列表中的數據類型沒有限制。此外,沒有有效的會員資格查詢。 ([x]是一個單鏈表。)可以做的是有效地迭代元素的順序順序。集合沒有排序,並且Set迭代速度不是非常快。

正如你可以看到,從東西一個或多個現有的集合構建的東西,一個新的集合,用於機器高效的工作,你想[x],不Set x

相關問題