所以我想在Haskell中创建一个程序,该程序通过从1到n的列表,每次出现可以除以3或7文本的数字,并且每当一个数字可以除以3和7它显示了一条短信。
这是我编写的代码,但我遇到了错误:
fuction' :: Int -> [Int]
fuction' n = take n [1..]
| (n `mod` 3) && (n `mod` 7 == 0) = error "BoomBANG!"
| n `mod` 3 == 0 = error " boom"
| n `mod` 7 == 0 = error " bang"
main = do
putStrLn ("a=")
a <- readLn
print (fuction' a)
希望有人可以告诉我我的错误在哪里。
答案 0 :(得分:1)
您获得的错误可能有两个来源
a)主函数输入错误
main = do putStrLn ("a=")
a <- readLn
print (fuction' a)
b)你的功能正在抛出错误
error "..."
抛出错误,你应该期待它。 所以我猜真正的答案应该包括一些提示,以摆脱错误
fuction :: Int -> [String]
fuction n = take n [1..]
| (n `mod` 3) && (n `mod` 7 == 0) = ..
| n `mod` 3 == 0 = ..
| n `mod` 7 == 0 = ..
| otherwise = .. -- you forgot one case
main :: IO ()
main = do putStrLn ("a=")
a <- readLn
mapM_ putStrLn (fuction a)
答案 1 :(得分:0)
error
导致程序以消息终止。您需要程序继续运行以输出其他消息。您可以通过从fuction'
返回消息来完成此操作,而不是让它尝试通过调用error
来终止程序来打印它们。
我们可以将程序分解成更小的部分。我们将Data.Maybe
导入catMaybes
以获取import Data.Maybe
,我们将在稍后使用。
message
Maybe
确定是否输出数字的消息。由于某些号码没有消息,我们会使用Just "themessage"
来存储Nothing
或message :: Int -> Maybe String
message n | (n `mod` 3 == 0) && (n `mod` 7 == 0) = Just "BoomBANG!"
| n `mod` 3 == 0 = Just " boom"
| n `mod` 7 == 0 = Just " bang"
| otherwise = Nothing
。
messages
map message
从整数列表中获取所有消息。 catMaybes
计算每个数字的消息。 Nothing
会从列表中删除Just
,并返回messages :: [Int] -> [String]
messages = catMaybes . map message
值中的内容列表。
fuction'
fuction' :: Int -> [String]
fuction' n = take n . messages $ [1..]
现在返回我们想要输出的所有消息,但是还没有输出它们,为下一步保存IO
printAll
map print
输出每条消息。 sequence_
使操作为列表中的每条消息输出消息。 printAll :: [String] -> IO ()
printAll = sequence_ . map print
执行所有操作,放弃他们拥有的任何结果
main
printAll
的最后一行更改为调用main = do
putStrLn ("a=")
a <- readLn
printAll (fuction' a)
以打印所有返回的消息。
{{1}}
答案 2 :(得分:0)
正如其他人所指出的,error
不是控制流,它只是针对灾难性的世界性问题。 (Haskell在编写自己的控制结构时非常灵活,所以你不需要那种东西。)
map
和transpose
解决此类问题的另一种方法是分别运行每项检查,然后transpose
结果
import Data.List (transpose)
ifMultipleOf n message is
= [if i `mod` n == 0 then message else "" | i<-is]
asSentences = unlines . map unwords
我基本上使用transpose
和unwords
作为一种广义的zipWith
。
boombang is = transpose
[map show is, ifMultipleOf 3 "boom" is, ifMultipleOf 7 "bang" is]
哪个给出了
ghci> boombang [1..21]
[["1","",""],["2","",""],["3","boom",""],["4","",""],["5","",""],["6","boom",""],["7","","bang"],["8","",""],["9","boom",""],["10","",""],["11","",""],["12","boom",""],["13","",""],["14","","bang"],["15","boom",""],["16","",""],["17","",""],["18","boom",""],["19","",""],["20","",""],["21","boom","bang"]]
ghci> putStrLn . asSentences $ boombang [1..21]
1
2
3 boom
4
5
6 boom
7 bang
8
9 boom
10
11
12 boom
13
14 bang
15 boom
16
17
18 boom
19
20
21 boom bang
答案 3 :(得分:0)
其他人已经指出了使用错误的危险。这是使用map函数解决方案的另一种尝试,并大量借用mapM_ @ AndrewC的解决方案,但将地图从IO monad中取出。如果您选择任何其他解决方案,我将解决我的解决方案。
function' :: Int -> [(Int, String)]
function' n = map (\x -> (x, compute x)) (take n [1..])
compute n
| ((n `mod` 3 == 0) && (n `mod` 7 == 0)) = "BoomBANG!"
| n `mod` 3 == 0 = " boom"
| n `mod` 7 == 0 = " bang"
| otherwise = ""
main = do
putStrLn ("a=")
a <- readLn
print (function' a)