2013-03-26 28 views
14

Ben formun anahtar/değer çiftlerini içeren bir dosyada okumaya çalışıyorum toplamak: çeşitli diğer hatlar ileHaskell eşdeğer

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

, önerildiği gibi. Bu, daha sonra anahtarları arayabileceğim bir haritaya gitmek istiyor.

İlk yaklaşımım satırları okumak ve [[String]] almak için '=' karakterine bölmek olacaktır. Scala, ben o zaman \x -> case x of a :: b :: _ -> (a,b) gibi bu durumda bir şey (kısmi fonksiyon alan ve işlev tanımlanmamış değerleri atmadan onu tanımlanan uygular collect, kullanırsınız. Haskell bunların hiçbirini eşdeğer var mı?

Bu gerçekleşmediği takdirde, nasıl biri benim çizgisinde ya da daha iyi bir yaklaşım kullanarak, ya Haskell bu yapacağını Genellikle bu Maybe tipi ve catMaybes ile yapılır

cevap

14

:?

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

Yani ayrıştırma işlevi varsa yazın :

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

sonra, çizgilerin içine girdi dizesini ayrıştırma Her satırı doğrulayarak ve sadece tanımlanmış değerleri dönerek harita oluşturabileceğini: s girişinizi dizesi olan

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

.

+15

N.B. -

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

Yani liste anlama ve gösterimi yapmak hem bu kadar desugars hangi fail yararlanarak CatMaybes. mapMaybe' Data.Maybe dan da 'haritası ayrıştırma = mapMaybe parse'. – dave4420

0

Liste Monad, aradığınız şeyi sağlar. Bu muhtemelen bir liste anlama yoluyla en kolay şekilde kullanılabilir, ancak aynı zamanda notasyon ile de çalışır. Şimdi Haskell kullanarak liste anlama versiyonu

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

- -

λ :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")] 

Ne oluyor desen eşleşme koşulu durumları hariç tutmak için olduğunu olduğunu don'

Öncelikle, burada referans için Scala uygulaması var Monad den fail yöntemiyle uyuşmaz.

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