Haskell中的“条件错误”

时间:2021-08-17 16:36:44

My original code is given below and works fine. I wanted to add range check of 'ind' and in the modified version I added an if statement. When I run it I get a "type error in conditional", and I THINK its because of the output defintion [[String]] not IO()?

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

Is there anyother way to check for the range of the value held in ind and produce an output like "error"/"outofrange" ?

有没有其他方法可以检查ind中保存的值的范围并产生“错误”/“outofrange”之类的输出?

original code

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

modified code

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

thanks,

5 个解决方案

#1


Replace putStrLn with error. That will cause your program to abort completely (unless something higher level catches the exception.)

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

The problem with what you've written is that you have declared a pure type, and then are trying to do IO, which isn't allowed.

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

#2


There are actually two errors in that code.

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

  • You need to use error, because it has type String -> a instead of String -> IO ()
  • 你需要使用错误,因为它有类型String - > a而不是String - > IO()

  • You apply > to [Int] and Int. Assuming that you want to test whether ind has length at most 3, you will have to call length.
  • 您将>应用于[Int]和Int。假设您要测试ind的长度是否最多为3,则必须调用length。

Example:

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

#3


As described in Ganesh's post, you want to do IO in a pure function, which isn't possible.

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

Ways to express your program (*you'll have to use length ind > 3 anyway)

表达你的程序的方法(*你将不得不使用长度> 3)

1 Use error (best way) as shown in the other posts

1使用其他帖子中显示的错误(最佳方式)

2 Use pattern guards (non exhaustive patterns-exception will occur)

2使用图案防护(非详尽模式 - 将发生异常)

3 Implement the IO properly:

3正确实施IO:

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

retrieve will have the type

检索将具有类型

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

4 Use Maybe to express that the computation may fail.

4使用Maybe表示计算可能失败。

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

#4


You can use a pattern guard for this:

您可以使用图案防护装置:

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

If you leave it like that you'll get a "Non-exhaustive patterns in function retrieve". You could also add another case with a custom error:

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

retrieve _ _ = error "Out of range"

#5


The then branch has type IO (), the else has type [[String]]. The types of the two if branches are different and there is no way to give a type to the whole if that doesn't cause a type conflict with one of the branches.

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

#1


Replace putStrLn with error. That will cause your program to abort completely (unless something higher level catches the exception.)

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

The problem with what you've written is that you have declared a pure type, and then are trying to do IO, which isn't allowed.

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

#2


There are actually two errors in that code.

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

  • You need to use error, because it has type String -> a instead of String -> IO ()
  • 你需要使用错误,因为它有类型String - > a而不是String - > IO()

  • You apply > to [Int] and Int. Assuming that you want to test whether ind has length at most 3, you will have to call length.
  • 您将>应用于[Int]和Int。假设您要测试ind的长度是否最多为3,则必须调用length。

Example:

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

#3


As described in Ganesh's post, you want to do IO in a pure function, which isn't possible.

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

Ways to express your program (*you'll have to use length ind > 3 anyway)

表达你的程序的方法(*你将不得不使用长度> 3)

1 Use error (best way) as shown in the other posts

1使用其他帖子中显示的错误(最佳方式)

2 Use pattern guards (non exhaustive patterns-exception will occur)

2使用图案防护(非详尽模式 - 将发生异常)

3 Implement the IO properly:

3正确实施IO:

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

retrieve will have the type

检索将具有类型

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

4 Use Maybe to express that the computation may fail.

4使用Maybe表示计算可能失败。

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

#4


You can use a pattern guard for this:

您可以使用图案防护装置:

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

If you leave it like that you'll get a "Non-exhaustive patterns in function retrieve". You could also add another case with a custom error:

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

retrieve _ _ = error "Out of range"

#5


The then branch has type IO (), the else has type [[String]]. The types of the two if branches are different and there is no way to give a type to the whole if that doesn't cause a type conflict with one of the branches.

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