我写了以下代码:
module Test where
import Char
import IO
main = do
str <- readFile "no.txt"
putStrLn (show(english str))
string2list :: String -> [String]
string2list "" = []
string2list s = words s
english :: String -> Int
english s
| head (string2list s) == "one" = 1
| head (string2list s) == "two" = 2
| head (string2list s) == "three" = 3
| head (string2list s) == "four" = 4
| head (string2list s) == "five" = 5
| head (string2list s) == "six" = 6
| head (string2list s) == "seven" = 7
| head (string2list s) == "eight" = 8
| head (string2list s) == "nine" = 9
| otherwise = error "not match"
在no.txt中:
one
two
three
four
....
编译并运行代码后,我得到了结果:
1
但我希望得到:
1
2
3
4
...
代码有什么问题?有帮助吗? THX!
答案 0 :(得分:6)
str
读取时, one\ntwo
不是String列表(它只是readFile
之类的字符串)。做
main = do
str <- readFile "no.txt"
mapM_ (\x -> putStrLn (show(english x))) $ lines str
代替main
并使用str
将lines
转换为列表(请参阅lines 的文档)。
答案 1 :(得分:5)
这不是你问题的答案,而是风格建议。您可以通过使用模式匹配并将head (string2list s)
替换为string2list
来摆脱那些冗长的words
事物;两者完全相同:
english s = case words s of
"one" :_ -> 1
"two" :_ -> 2
"three" :_ -> 3
"four" :_ -> 4
"five" :_ -> 5
"six" :_ -> 6
"seven" :_ -> 7
"eight" :_ -> 8
"nine" :_ -> 9
_ -> error "no match"
答案 2 :(得分:2)
你的问题是english
只看第一个单词。您的文件以
"one\ntwo\nthree\nfour"
然后words
将其变为:
["one","two","three","four"]
使用head on that给你:
"one"
因此1
被打印出来。
Instaid我们想在所有单词上使用英语。那是map
进来的时候
方便,但在这种情况下,我们将IO操作映射到列表,所以我们想使用mapM
。此外,我们对IO行动的结果不感兴趣(我们只是希望行动发生)所以我们使用mapM_
:
import Control.Monad
main = do
str <- readFile "no.txt"
mapM_ (print . english) (words str)
english "one" = 1
english "two" = 2
english "three" = 3
english "four" = 4
english "five" = 5
english "six" = 6
english "seven" = 7
english "eight" = 8
english "nine" = 9
请注意,可以使用map
mapM
的{{1}} instaid来编写此内容,方法是先将["one","two","three",...]
转换为["1","2","3"]
,然后将这些字符串合并,然后使用putStrLn
},但上述方式更短,更惯用。