Haskell中的“条件错误”

时间:2009-05-23 16:56:08

标签: haskell

我的原始代码如下,并且工作正常。我想添加'ind'的范围检查,在修改后的版本中我添加了一个if语句。当我运行它时,我得到一个“有条件的类型错误”,我认为它是因为输出定义[[String]]而不是IO()?

有没有其他方法可以检查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 个答案:

答案 0 :(得分:6)

该代码实际上有两个错误。

  • 您需要使用error,因为它的类型为String -> a,而不是String -> 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]

答案 1 :(得分:5)

putStrLn替换为error。这将导致您的程序完全中止(除非某些更高级别捕获异常。)

您编写的内容的问题是您已声明纯类型,然后尝试执行IO,这是不允许的。

答案 2 :(得分:3)

如Ganesh的帖子中所述,您希望在pure function中执行IO,这是不可能的。

表达程序的方法(*你必须使用length ind > 3

1使用error(最佳方式),如其他帖子所示

2使用模式保护(non exhaustive patterns - 将发生异常)

3正确实施IO:

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

retrieve将具有

类型
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]

答案 3 :(得分:2)

您可以使用模式防护:

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

如果你这样离开,你会得到一个“函数检索中的非详尽模式”。您还可以添加另一个包含自定义错误的案例:

retrieve _ _ = error "Out of range"

答案 4 :(得分:1)

then分支的类型为IO ()else的类型为[[String]]。两个if分支的类型是不同的,并且无法为整个if提供不会导致与其中一个分支发生类型冲突的类型。