这是我遇到的一个家庭作业问题:
输入一个大于或等于0的整数。将它乘以5,将6加到乘积上,乘以4,加9并乘以5.然后,删除最后一个数的最后两位数并减去1输出答案。
这是我的代码:
1 main = do
2 putStrLn "enter a non-negative integer: "
3 input <- getLine
4 let i = (read input :: Int)
5 print ((((i * 5) + 6) * 4 + 9) * 5)/100-1
在这里,我试图将最后两位数除以100,因为这适用于其他语言。 但是,它给了我这个错误,我不确定它的含义:
$ runhaskell Computations.hs
Computations.hs:5:5: error:
• No instance for (Fractional (IO ())) arising from a use of ‘/’
• In the first argument of ‘(-)’, namely
‘print ((((x * 5) + 6) * 4 + 9) * 5) / 100’
In a stmt of a 'do' block:
print ((((x * 5) + 6) * 4 + 9) * 5) / 100 - 1
In the expression:
do { putStrLn "enter a non-negative integer: ";
input1 <- getLine;
let x = (read input1 :: Int);
print ((((x * 5) + 6) * 4 + 9) * 5) / 100 - 1 }
Computations.hs:5:5: error:
• No instance for (Num (IO ())) arising from a use of ‘-’
• In a stmt of a 'do' block:
print ((((x * 5) + 6) * 4 + 9) * 5) / 100 - 1
In the expression:
do { putStrLn "enter a non-negative integer: ";
input1 <- getLine;
let x = (read input1 :: Int);
print ((((x * 5) + 6) * 4 + 9) * 5) / 100 - 1 }
In an equation for ‘main’:
main
= do { putStrLn "enter a non-negative integer: ";
input1 <- getLine;
let x = ...;
.... }
那么,任何人都可以解释错误的含义吗?
还有其他解决办法比除数除外更好吗?
如何删除任意位置的数字?例如,从整数中删除第一个,第二个和第六个数字?
ps:如果正确完成,输入和输出应匹配。
更新:我已将“/”改为“div”,它给了我这个:
Computations.hs:5:12: error:
• Couldn't match expected type ‘(Integer -> Integer -> Integer)
-> Integer -> Integer’
with actual type ‘Int’
• The function ‘(((i * 5) + 6) * 4 + 9) * 5’
is applied to two arguments,
but its type ‘Int’ has none
In the first argument of ‘(-)’, namely
‘((((i * 5) + 6) * 4 + 9) * 5) div 100’
In the first argument of ‘print’, namely
‘(((((i * 5) + 6) * 4 + 9) * 5) div 100 - 1)’
这部分很奇怪:“函数'(((i * 5)+ 6)* 4 + 9)* 5'应用于两个参数”,为什么haskell将其解释为函数?
答案 0 :(得分:3)
删除任意位置的数字是一个有趣的问题。这可能是最简单的方法,转换为字符串并执行字符串操作,然后作为Int读回。由于Int
同时实现Show
和Read
,您可以执行以下操作:
type Digit = Int
removeDigits :: [Digit] -> Int -> Int
removeDigits digits = read . go 1 . show
where
go _ [] = []
go i (c:cs) | i `elem` digits = go cs (i+1)
| otherwise = c : go cs (i+1)
-- N.B. I chose 1-indexing here instead of 0-indexing because of your word choice
-- "remove the first, second, and sixth digits" maps naturally to [1, 2, 6],
-- though programmers may find that off-putting. YMMV.
removeDigits
这里可以重写为
read [c | (i, c) <- zip [1..] (show n), i `notElem` digits]
答案 1 :(得分:3)
任何人都可以解释错误的含义吗?
第一行中的优先级为off - 中缀函数(如/
)通常具有比普通函数更高的优先级,因此print (...) / 100
等同于(print ...) / 100
,这显然是有问题的。您可以将所有内容括在括号中,或使用$
函数:
print $ ((((i * 5) + 6) * 4 + 9) * 5) / 100 - 1
现在,由于您已将i
限制为Int
,因此仍会出现错误:/
仅针对Fractional
类型类的实例定义,并且Int
不是。您需要整数除法div
或quot
,它仅在Integral
上运行(其中Int
是一个实例),并根据需要执行截断:
print $ ((((i * 5) + 6) * 4 + 9) * 5) `div` 100 - 1
注意反引号(`),它允许使用正常函数作为中缀。你可以写成:
print $ (div ((((i * 5) + 6) * 4 + 9) * 5) 100) - 1
但是后面的括号让事情变得难以阅读。
还有其他解决方案比按除数截断更好吗?
一般情况下可能没有,但是as mentioned on your other question,这个特定的等式总会给你与输入相同的结果,所以你可以写:
main = getLine >>= print
如何删除任意位置的数字?
转换为字符串并删除字符可能是您最好的选择。像下面这样的东西会起作用,虽然它可能有点密集:
removeDigits :: [Int] -> Int -> Int
removeDigits indices x = read . reverse . filterIndices indices . reverse . show $ x
filterIndices :: [Int] -> [a] -> [a]
filterIndices inds elems = map snd . filter ((`notElem` inds) . fst) . zip [1..] $ elems
请注意,这会将最后一位数字视为“第一”数字 - 用数字引用数字会更自然。
(在我看来)更容易阅读现有代码的表示形式是:
transform = (subtract 1) . (`quot` 100) . (*5) . (+9) . (*4) . (+6) . (*5)
通过这种写作方式,组合会覆盖算术优先级法则,让我们把它写成如何阅读(“时间5,加6,时间4,......”)。我们必须使用subtract 1
,因为-1
被解释为文字值-1
,而不是一元函数。