2013-03-26 37 views
14

Tôi đang cố gắng để đọc trong một tập tin chứa các cặp/giá trị quan trọng của hình thức:Haskell tương đương với scala thu thập

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

Với dòng khác nhau, như đề xuất. Điều này muốn đi vào một bản đồ mà tôi có thể tra cứu các khóa từ đó.

cách tiếp cận ban đầu của tôi sẽ được đọc trong các dòng và chia trên nhân vật '=' để có được một [[String]]. Trong Scala, sau đó tôi sẽ sử dụng collect, trong đó có một chức năng một phần (trong trường hợp này một cái gì đó như \x -> case x of a :: b :: _ -> (a,b) và áp dụng nó, nơi nó được xác định, ném đi các giá trị mà chức năng là không xác định. không đó, làm thế nào người ta sẽ làm điều này trong Haskell, hoặc dọc theo các đường tôi hoặc sử dụng một cách tiếp cận tốt hơn

Trả lời

14

Thông thường điều này được thực hiện với sự Maybe loại và catMaybes:

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

Vì vậy, nếu chức năng phân tích của bạn có kiểu :

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

sau đó bạn có thể xây dựng bản đồ bằng cách phân tích các chuỗi đầu vào dòng, xác nhận mỗi dòng và trở về chỉ là giá trị được xác định:

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

nơi s là chuỗi đầu vào của bạn.

+15

n.b. 'catMaybes. map parse = mapMaybe parse', trong đó 'mapMaybe' cũng từ Data.Maybe. – dave4420

0

danh sách Monad cung cấp những gì bạn đang tìm kiếm. Điều này có thể dễ dàng được tận dụng thông qua một danh sách hiểu, mặc dù, nó hoạt động với ký hiệu là tốt.

Thứ nhất, đây là việc thực hiện Scala để tham khảo -

// 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)) 

Bây giờ phiên bản danh sách hiểu sử dụng 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")] 

gì đang xảy ra là điều kiện mô hình kết hợp được lọc ra những trường hợp mà don' t khớp với phương pháp fail từ Monad.

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

Vì vậy, cả hai danh sách hiểu và làm ký hiệu cũng đang lợi dụng fail, mà desugars này -

map (splitOn "=") xs >>= (
    \s -> case s of 
    [k, v] -> return (k, v) 
    _ -> fail "" 
) 
Các vấn đề liên quan