我的原始代码如下,并且工作正常。我想添加'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]
感谢,
答案 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
提供不会导致与其中一个分支发生类型冲突的类型。