2009-05-23 57 views
0

我的原始代碼如下所示,工作正常。我想添加'ind'的範圍檢查,並在修改後的版本中添加了if語句。當我運行它時,我得到一個「有條件的類型錯誤」,並且由於輸出定義[[String]]而不是IO(),我認爲它是它的?Haskell中的「條件類型錯誤」

是否有其他方法檢查ind中保存的值的範圍並生成「錯誤」/「超出範圍」等輸出?

原始代碼

retrieve :: [Int] -> [[String]] -> [[String]] 
retrieve [] dat = [[]] 
retrieve ind dat = [exC ind d | d <- dat] 

修改的碼

retrieve :: [Int] -> [[String]] -> [[String]] 
retrieve [] dat = [[]] 
retrieve ind dat = if ind>3 
         then putStrLn "not found" 
         else [exC ind d | d <- dat] 

感謝,

回答

5

替換putStrLnerror。這將導致您的程序完全中止(除非更高級別捕捉到異常。)

您寫的內容的問題是您聲明瞭純類型,然後嘗試執行IO, t允許。

2

您可以使用模式後衛這一點:

retrieve :: [Int] -> [[String]] -> [[String]] 
retrieve [] dat = [[]] 
retrieve ind dat | ind <= 3 = [exC ind d | d <- dat] 

如果你離開它一樣,你會得到一個「函數檢索非詳盡模式」。你也可以用自定義錯誤添加另一種情況:

retrieve _ _ = error "Out of range" 
+0

謝謝大家!很好的幫助! – pier 2009-05-23 18:07:00

1

then分支具有類型IO(),該else具有類型[[String]]。兩個if分支的類型是不同的,並且沒有辦法給整個if賦予一個類型,但不會導致與其中一個分支發生類型衝突。

6

該代碼實際上有兩個錯誤。

  • 您需要使用error,因爲它有一個類型,而不是String -> aString -> IO()
  • 您申請>[Int]Int。假設您要測試ind的長度是否最多爲3,則必須致電length

例子:

retrieve :: [Int] -> [[String]] -> [[String]] 
retrieve [] dat = [[]] 
retrieve ind dat | length ind > 3 = error "not found" 
       | otherwise  = [exC ind d | d <- dat] 
+0

第二點不一定是錯誤。他本可以將[Int]作爲Ord類型類的一個實例。 (但我不認爲是這樣) – Jonas 2009-05-23 17:26:22

3

正如Ganesh的崗位描述,你想要做的IO在pure function,這是不可能的。

的方式來表達你的程序(*您必須使用length ind > 3反正)

1使用error(最好的方法),如其他職位所示

2使用模式衛士(non exhaustive patterns -exception會發生)

3正確地實現的IO:

retrieve ind dat = if ind >= 3 
        then do return [exC ind d | d <- dat ] 
        else do putStrLn "error"; return [[]] 

retrieve WIL l有類型

retrieve :: [Int] -> [[String]] -> IO [[String]] 

4使用Maybe表示計算可能會失敗。

retrieve :: [Int] -> [[String]] -> Maybe [[String]] 
retrieve [] dat = [[]] 
retrieve ind dat | length ind > 3 = Nothing 
       | otherwise  = Just [exC ind d | d <- dat]