2011-01-22 55 views
5

所以,我有多重定義(後衛)的函數,具體取決於它匹配,我想有它要麼返回(A,B)或[ (a,b)],但是編譯器正在拋出錯誤,因爲它們是不同的類型。我試圖用Either解決這個問題,但可能沒有正確使用它:P。任何幫助?在Haskell如何讓一個函數返回不同類型

+1

你不能這樣做,因爲直接函數的返回類型必須在編譯時是已知的,而守衛在運行時間相匹配。 但是你確定你真的想要返回一個不同的類型嗎?如果您打算對結果進行模式匹配以區分這兩種情況,則兩者都可以。或者,也許單身人士名單將在第一種情況下做?你能提供更多關於你將要做什麼的細節嗎? – b0fh

+0

http://paste.pocoo.org/show/325066/是我迄今爲止的功能 –

+0

這就像閱讀一個魔法。它應該是什麼意思? – luqui

回答

9

Either - 或自定義數據類型等同於它 - 是唯一這樣做的方法。下面是一個愚蠢的例子:

stuff :: Int -> Either (Int,Int) [(Int,Int)] 
stuff 0 = Left (0, 0) 
stuff n = Right [ (x,x) | x <- [0..n] ] 

然後,當有人調用這個函數,它們可以模式匹配,找出其中兩種類型的,它返回:

foo n = case stuff n of 
      Left (a,b) -> ... 
      Right pairs -> ... 

然而,知道也不關心你的問題,一般來說,我會建議更多地考慮你的函數的含義。它需要什麼,它會返回什麼?精確,數學。答案越簡單,這個函數就會越順利地與你的程序的其餘部分和Haskell的概念一起工作。對於我來說,在這樣的描述中,Either很少出現。你如何統一這兩個結果?也許你只是返回單身人士名單[(a,b)]而不是Left (a,b),如果這對您的功能有意義。

Haskell沒有用的功能,嘗試是太聰明瞭,你可能會從Python或jQuery的使用類型發揮出色。保持它愚蠢和精確 - 從構成這些簡單的作品。如果您對此感到好奇,可以提出另一個問題,提供有關您的問題的更多詳細信息,您要完成的內容以及爲什麼要以這種方式工作。很抱歉的說教:-)

+0

我想補充一下,我們想要的類型系統的屬性是* preserve *的屬性:鬆散地說,如果我們有類型'stuff :: Int - >(Int,Int) '然後調用'stuff 7'將會減少到'[(x,x)|在類型爲[[(Int,Int)]''的示例中,x < - [0..n]'。這與聲明返回類型的'stuff'不同,因此該類型不會被保留。如果我們相信任何類型的系統,就必須排除這種差異。因此,類型檢查程序拒絕我們的程序爲不正確的類型。 –

0

函數只能返回一個類型,因爲會爲你工作,因爲它會對你的函數返回類型是(A,B)(A·B)]。

我不知道哪裏出了問題你是如何使用這兩種,但這裏是它的使用的一個簡單的例子:

test a b = 
    if a == True 
    then Left (a,b) 
    else Right [(a,b)] 
+0

所以這裏是我的功能現在:http://paste.pocoo.org/show/325090/ 這裏的錯誤:HTTP://paste.pocoo。 org/show/325093/ –

+0

@Chris'Right lgst i'' should'Right(lgst i)'。 – dave4420

+0

好的,所以http://paste.pocoo.org/show/325143/的作品,但後兩個警衛需要看起來像http://paste.pocoo.org/show/325144/這給了我:http:///paste.pocoo.org/show/325145/ –

相關問題