这有效:
c <- fmap lines (readFile "d:\\tmp\\h.txt")
let h = map (read :: String -> Int) c
而那些不编译的那两行的“叠加”
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")]
答案 0 :(得分:10)
您将map
从“叠加”(作文)中删除:
h <- fmap (map (read :: String -> Int)) $ fmap lines (readFile "d:\\tmp\\h.txt")
您可以将其简化为
h <- fmap (map (read :: String -> Int) . lines) (readFile "d:\\tmp\\h.txt")
如果您在源文件的顶部放置import Control.Applicative
行(如果您以交互方式使用ghci,则输入:m +Control.Applicative
),您可以使用<$>
运算符代替{ {1}}让它看起来更干净。 (他们做同样的事情,他们的拼写不同。)
fmap
最后,如果您确实需要类型签名,您可能会发现它在行尾看起来更清晰。
h <- map (read :: String -> Int) . lines <$> readFile "d:\\tmp\\h.txt"
答案 1 :(得分:9)
[int(i) for i in open("d:\\tmp\\h.txt")]
将计算与行动分开:
return . map read . lines =<< readFile "d:\\tmp\\h.txt"
答案 2 :(得分:8)
重。第二个问题:使用Applicative
会使其更具可读性:
map read . lines <$> readFile "file"
您可以避免提供read
类型签名,具体取决于您的代码的其余部分,这将是更好的