簡體   English   中英

Haskell相當於scala收集

[英]Haskell equivalent of scala collect

我正在嘗試讀取包含表單的鍵/值對的文件:

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

如所建議的那樣,有各種其他線路。 這想要進入我可以從中查找鍵的地圖。

我最初的方法是讀取行並在'='字符上拆分以獲得[[String]] 在Scala中,我會使用collect ,它接受一個部分函數(在這種情況下類似於\\x -> case x of a :: b :: _ -> (a,b)並將其應用於定義的地方,扔掉函數未定義的值.Haskell有沒有相應的這個?

如果不這樣做,那么在Haskell中如何做到這一點,無論是沿着我的方向還是使用更好的方法?

通常,這是使用Maybe類型和catMaybes

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

所以如果你的解析函數有類型:

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

然后,您可以通過將輸入字符串解析為行來構建映射,驗證每一行並僅返回定義的值:

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

其中s是您的輸入字符串。

List Monad提供您正在尋找的東西。 這可能是通過列表理解最容易利用的,盡管它也適用於符號。

首先,這是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")]

發生的事情是模式匹配條件是使用Monadfail方法過濾掉不匹配的情況。

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

所以列表理解和做法都是利用fail ,這對此有所貶低 -

map (splitOn "=") xs >>= (
  \s -> case s of
    [k, v] -> return (k, v)
    _ -> fail ""
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM