14

次の形式のキーと値のペアを含むファイルを読み込もうとしています。

#A comment
a=foo
b=bar
c=baz
Some other stuff

提案されているように、他のさまざまな行で。これは、キーを検索できるマップに移動したいと考えています。

私の最初のアプローチは、行を読み、「=」文字で分割して。を取得すること[[String]]です。次に、Scalaでcollect、部分関数をとるを使用します(この場合、のようなもの\x -> case x of a :: b :: _ -> (a,b)を定義された場所に適用し、関数が定義されていない場所の値を破棄します。Haskellにはこれに相当するものがありますか?

それが失敗した場合、私の方針に沿って、またはより良いアプローチを使用して、Haskellでこれをどのように行うでしょうか?

4

2 に答える 2

15

通常、これはMaybeタイプとcatMaybes:で行われます。

catMaybes :: [Maybe a] -> [a]

したがって、解析関数のタイプが次の場合:

parse :: String -> Maybe (a,b)

次に、入力文字列を行に解析し、各行を検証して、定義された値だけを返すことにより、マップを作成できます。

Map.fromList . catMaybes . map parse . lines $ s

s入力文字列はどこにありますか。

于 2013-03-26T10:24:45.633 に答える
0

リストモナドはあなたが探しているものを提供します。これはおそらくリスト内包表記を介して最も簡単に活用できますが、do表記でも機能します。

まず、参考のためにScalaの実装を示します-

// Using .toList for simpler demonstration
scala> val xs = scala.io.Source.fromFile("foo").getLines().toList
List[String] = List(a=1, b=2, sdkfjhsdf, c=3, sdfkjhsdf, d=4)

scala> xs.map(_.split('=')).collect { case Array(k, v) => (k, v) }
List[(String, String)] = List((a,1), (b,2), (c,3), (d,4))

Haskellを使用したリスト内包バージョン-

λ :m + Data.List.Split
λ xs <- lines <$> readFile "foo"
λ xs
["a=1","b=2","sdkfjhsdf","c=3","sdfkjhsdf","d=4"]

-- List comprehension
λ [(k, v) | [k, v] <- map (splitOn "=") xs]
[("a","1"),("b","2"),("c","3"),("d","4")]

-- Do notation
λ do { [k, v] <- map (splitOn "=") xs; return (k, v) }
[("a","1"),("b","2"),("c","3"),("d","4")]

fail何が起こっているのかというと、パターン一致条件は、からのメソッドを使用して一致しないケースを除外しているということですMonad

λ fail "err" :: [a]
[]

したがって、リスト内包表記と表記法の両方が活用failされており、これはこれに脱糖します-

map (splitOn "=") xs >>= (
  \s -> case s of
    [k, v] -> return (k, v)
    _ -> fail ""
)
于 2017-02-22T02:14:03.990 に答える