2009-05-23 38 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]