这有效:
c <- fmap lines (readFile "d:\\tmp\\h.txt")
let h = map (read :: String -> Int) c
Run Code Online (Sandbox Code Playgroud)
而那些"不能编译"的那两行的"叠加"
fmap (read :: String -> Int) $ fmap lines (readFile "d:\\tmp\\h.txt")
它会产生错误:
interactive:1:36:
Couldn't match expected type `Char' with actual type `[Char]'
Expected type: String -> String
Actual type: String -> [String]
In the first argument of `fmap', namely `lines'
In the second argument of `($)', namely
`fmap lines (readFile "d:\\tmp\\h.txt")
为什么它不编译以及如何在一行中执行此操作?我想要的是实现python的简单性
[int(i) for i in open("d:\\tmp\\h.txt")]
Run Code Online (Sandbox Code Playgroud)
dav*_*420 11
你离开map了你的"叠加"(作曲):
h <- fmap (map (read :: String -> Int)) $ fmap lines (readFile "d:\\tmp\\h.txt")
Run Code Online (Sandbox Code Playgroud)
你可以简化它
h <- fmap (map (read :: String -> Int) . lines) (readFile "d:\\tmp\\h.txt")
Run Code Online (Sandbox Code Playgroud)
如果您import Control.Applicative在源文件的顶部放置一行(或者:m +Control.Applicative如果您以交互方式使用ghci则输入),则可以使用<$>运算符而不是fmap使其看起来更干净.(它们完全相同,它们的拼写方式不同.)
h <- map (read :: String -> Int) . lines <$> readFile "d:\\tmp\\h.txt"
Run Code Online (Sandbox Code Playgroud)
最后,如果您确实需要类型签名,您可能会发现它在行尾看起来更清晰.
h <- map read . lines <$> readFile "d:\\tmp\\h.txt" :: IO [Int]
Run Code Online (Sandbox Code Playgroud)
[int(i) for i in open("d:\\tmp\\h.txt")]
Run Code Online (Sandbox Code Playgroud)
将计算与操作分开:
return . map read . lines =<< readFile "d:\\tmp\\h.txt"
Run Code Online (Sandbox Code Playgroud)
回覆.你的第二个问题:使用Applicative会使它更具可读性:
map read . lines <$> readFile "file"
Run Code Online (Sandbox Code Playgroud)
您可以避免提供read类型签名,具体取决于您的代码的其余部分,这将是更好的选择