リストモナドはあなたが探しているものを提供します。これはおそらくリスト内包表記を介して最も簡単に活用できますが、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 ""
)