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 typeString -> a
instead ofString -> IO ()
- You apply
>
to[Int]
andInt
. Assuming that you want to test whetherind
has length at most 3, you will have to calllength
.
你需要使用错误,因为它有类型String - > a而不是String - > IO()
您将>应用于[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 typeString -> a
instead ofString -> IO ()
- You apply
>
to[Int]
andInt
. Assuming that you want to test whetherind
has length at most 3, you will have to calllength
.
你需要使用错误,因为它有类型String - > a而不是String - > IO()
您将>应用于[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分支的类型是不同的,如果不会导致与其中一个分支的类型冲突,则无法为整体提供类型。