2011-10-09 73 views
2
data Test = [Int] | Int 

foobar :: Test -> Int 

如果我想要的東西,像foobar的[1,2,3] = 1,foobar的1 = 1。在二郎這將是所有的如何在不同類型上進行模式匹配?

foobar(X) when is_list(X) -> hd(X); 
foobar(X) -> X. 
+0

你有這個特定用例?或者你只是好奇? (不是說有什麼不對的好奇心!)爲了讓你問你要爭取類型系統一點點的行爲,所以可能有解決問題無論你工作更哈斯克爾-Y方式。 – Zopa

+0

只是好奇。我遇到過幾個我想要這樣的地方。我還沒有做任何有用的事情。 –

回答

13

首先,你的數據聲明是無效的。在Haskell中,你必須開始一個數據聲明與數據構造,稍後在匹配。例如,你的類型Test將被寫入

data Test = TLst [Int] | TInt Int 

現在,你可以簡單地匹配類型,構造;它的字段是一個列表或者一個int,取決於你符合其中的構造函數:

foobar :: Test -> Int 
foobar (TLst (x:xs)) = x 
foobar (TLst [])  = error "empty list passed to foobar" 
foobar (TInt x)  = x 
+3

當你說你的意思是「數據構造」「類型構造」。 – sepp2k

3

首先,這不是有效的Haskell語法:

data Test = [Int] | Int -- this doesn't work 

的替代品需要自己的構造函數。因此,這是有效的:

data Test = TestA [Int] | TestB Int 

然後你可以模式匹配這樣的:

foobar :: Test -> Int 
foobar (TestA listOfInt) = length listOfInt 
foobar (TestB int)  = int 
7

另一種方法來此是使用類型類,像這樣:

class Test a where 
    foobar a -> Int 

instance Test Int where 
    foobar x = x 

instance Test [Int] where 
    foobar [] = error "Empty list" 
    foobar (x:_) = x 

模式匹配在這裏是隱含的 - 傳遞給foobar的類型決定了我們選擇哪個實例。

但你可能不希望除非有一個在你的問題的對稱性,使得它明智的思考INT和[INT]作爲同樣的事情的兩個例子是做這樣的事情。你的類型越適合你解決的問題,類型分析者就可以幫助你。

+0

健全的建議。 +1。 – AndrewC

相關問題