Haskell 从整数中删除数字

Haskell 从整数中删除数字,haskell,Haskell,我遇到了一个家庭作业问题: 输入一个大于或等于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) *

我遇到了一个家庭作业问题:

输入一个大于或等于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

这一部分很奇怪:“函数“((i*5)+6)*4+9)*5”应用于两个参数”,为什么haskell将其解释为函数?

删除任意位置的数字是一个有趣的问题。通过转换为字符串并执行字符串操作,然后作为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]

read[c |(i,c)删除任意位置的数字是一个有趣的问题。通过转换为字符串并执行字符串操作,然后作为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]

read[c|(i,c)有人能解释一下错误的含义吗?

第一行中的优先级是非中缀函数(如
/
)通常比普通函数具有更高的优先级,因此
print(…)/100
相当于
(print…)/100
,这显然是有问题的。您可以将所有函数都用括号括起来,或者使用
$
函数:

print $ ((((i * 5) + 6) * 4 + 9) * 5) / 100 - 1
现在,由于您已将
i
约束为
Int
,这仍然会给出一个错误:
/
仅为
分数型
类型类的实例定义,而
Int
不是。您想要整数除法、
div
quot
,它只对
整数型
进行操作(其中
Int
是一个实例)并根据需要执行截断:

print $ ((((i * 5) + 6) * 4 + 9) * 5) `div` 100 - 1
请注意倒勾(`),它允许在中缀中使用普通函数。您可以这样写:

print $ (div ((((i * 5) + 6) * 4 + 9) * 5) 100) - 1
但是括号让人很难理解


还有比除数截断更好的解决方案吗?

一般来说,可能不会,但是,这个特定的等式将始终为您提供与输入相同的结果,因此您可以只写:

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,…)。我们必须使用
减去1
,因为
-1
被解释为文本值
-1
,而不是一元函数。

有人能解释错误的含义吗?

第一行中的优先级是非中缀函数(如
/
)通常比普通函数具有更高的优先级,因此
print(…)/100
相当于
(print…)/100
,这显然是有问题的。您可以将所有函数都用括号括起来,或者使用
$
函数:

print $ ((((i * 5) + 6) * 4 + 9) * 5) / 100 - 1
现在,由于您已将
i
约束为
Int
,这仍然会给出一个错误:
/
仅为
分数型
类型类的实例定义,而
Int
不是。您想要整数除法、
div
quot
,它只对
整数型
进行操作(其中
Int
是一个实例)并根据需要执行截断:

print $ ((((i * 5) + 6) * 4 + 9) * 5) `div` 100 - 1
请注意倒勾(`),它允许在中缀中使用普通函数。您可以这样写:

print $ (div ((((i * 5) + 6) * 4 + 9) * 5) 100) - 1
但是括号让人很难理解


还有比除数截断更好的解决方案吗?

一般来说,可能不会,但是,这个特定的等式将始终为您提供与输入相同的结果,因此您可以只写:

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
,而不是一元函数。

使用
div
,而不是
/
。整数除法是
div
,而不是
//code>@chepner,如果您省略了所述的前提条件,正确的除法操作将是
quot
,而不是
div
。如果你想像操作符一样使用
div,你必须把它放在反引号中。仅供参考,你可以使用下面的代码:
transform=(减法1)。(`quot`100)。(*5)。(+9)。(*4)。(+6)。(*5)
,尽管答案是“还有比用除数表示更好的解决方案吗?”已在my中给出,因此可能不需要在此处重复。使用
div
,而不是
//code>。整数除法是
div
,而不是
//code>@chepner,如果省略所述的前置条件,正确的除法操作将是
quot
,而不是
div
。您必须将
div
放入