我正在开发一个haskell项目并且有一个minmax函数,它获取列表的最小值和最大值,并将它们返回到元组对中,如下所示:
λ> minmax [1,2,3]
(1,3)
λ> minmax [4,2,5,9]
(2,9)
现在我正在实现一个递归循环的用户输入列表,直到放入取消输入然后列表完成然后需要利用我的minmax函数,我遇到的问题是它显然不是一个类型的完成后的简单列表,因为它给我带来了类型错误。
minmax :: (Ord a) => [a] -> (a,a)
minmax [] = error "Null"
minmax (x:xs) = (minimum (x:xs), maximum (x:xs))
convertIO :: IO Int
convertIO = do
line <- getLine
return (read line :: Int)
minmaxlist :: IO [Int]
minmaxlist = do
number <- convertIO
if(number /= 0)
then (do
int_list <- minmaxlist
return (minmax (number:int_list)))
else return []
给我这个特定的错误:
Couldn't match expected type `[Int]' with actual type `(Int, Int)'
虽然整数列表正是我通过的数字(number:int_list),如果我确实传递了一个整数列表,它会返回元组。为什么在这里给我带来错误?是否与IO类型有关?
答案 0 :(得分:2)
minmaxlist :: IO [Int]
声明minmaxlist
是IO
操作,返回Int
列表。但是,它会尝试返回minmax
(return (minmax (number:int_list)))
)的结果,其类型为(Int, Int)
。
那么,您希望minmaxlist
返回什么?
答案 1 :(得分:2)
你的想法很好 - minmax
和你IO [Int]
的制作方式似乎是合理的 - 我只是将minmax
的应用推出列表生成全部togehter:
module Main where
minmax :: (Ord a) => [a] -> (a,a)
minmax [] = error "Null"
minmax (x:xs) = (minimum (x:xs), maximum (x:xs))
convertIO :: IO Int
convertIO = do
line <- getLine
return (read line :: Int)
ioInts :: IO [Int]
ioInts = do
number <-convertIO
if number /= 0
then do
int_list <- ioInts
return (number:int_list)
else return []
minmaxIO :: IO (Int,Int)
minmaxIO = do
list <- ioInts
return $ minmax list
main :: IO ()
main = do
val <- minmaxIO
print val
你可以通过像(<$>)
这样的运算符缩短这一点,但我认为你对do
符号更为舒服
正如您所看到的,我刚刚添加了另一个IO
计算minmaxIO
,它将minmax
应用于ioInts
生成的列表(我从minmaxlist
重命名) - 其他的东西,如果基本上仍然是你的
答案 2 :(得分:0)
你非常接近 - 不要使用元组,而是返回一个列表
minmax :: (Ord a) => [a] -> [a]
minmax [] = error "Null"
minmax xs = [minimum xs, maximum xs]