2

これは機能します:

c <- fmap lines (readFile "d:\\tmp\\h.txt")  
let h = map (read :: String -> Int) c 

これらの2行の「重ね合わせ」はコンパイルされません

fmap (read :: String -> Int) $ fmap lines (readFile "d:\\tmp\\h.txt")

エラーが発生します:

インタラクティブ:1:36:
    予期されたタイプ`Char'と実際のタイプ`[Char]'を一致させることができませんでした
    予想されるタイプ:文字列->文字列
      実際のタイプ:文字列->[文字列]
    `fmap'の最初の引数、つまり` lines '
    `($)'の2番目の引数、つまり
      `fmap行(readFile" d:\\ tmp \\ h.txt ")

なぜコンパイルされないのか、そしてこれを1行で行う方法は?私が欲しいのはPythonのシンプルさを実現することです

[int(i) for i in open("d:\\tmp\\h.txt")]
4

3 に答える 3

11

あなた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てください)、見栄えを良くする<$>代わりに演算子を使用できますfmap。(スペルが違うだけで、やっていることは同じです。)

h <- map (read :: String -> Int) . lines <$> readFile "d:\\tmp\\h.txt"

最後に、型シグネチャが必要な場合は、行末の方が明確に見える場合があります。

h <- map read . lines <$> readFile "d:\\tmp\\h.txt" :: IO [Int]
于 2012-04-20T15:50:13.547 に答える
9
[int(i) for i in open("d:\\tmp\\h.txt")]

計算をアクションから分離する:

return . map read . lines =<< readFile "d:\\tmp\\h.txt"
于 2012-04-20T15:53:04.873 に答える
8

再。2番目の質問:使用Applicativeすると読みやすくなります:

map read . lines <$> readFile "file"

コードの残りの部分によっては、型署名の付与を回避できる場合がreadあります。これは望ましいことです。

于 2012-04-20T16:00:37.813 に答える