2015-07-08 1 views
1

Я работаю над фрагментом кода, где мне нужно обработать списки кортежей, где и порядок и имена «ключей» (fst s кортежей) соответствуют определенному шаблон. Я выполняю отказоустойчивость, проверяя и (при необходимости) генерируя действительный список на основе ввода.Заполнение списка кортежей семантическим способом

Вот пример того, что я имею в виду:

Учитывая шаблон ключей, ["hello", "world", "this", "is", "a", "test"] и список [("hello", Just 1), ("world", Just 2), ("test", Just 3)], передавая его к моей функции validate бы привести к сбою проверки - как порядок и значения ключей не совпадают с шаблоном.

При отсутствии проверки, я хочу, чтобы создать новый список, который будет выглядеть [("hello", Just 1), ("world", Just 2), ("this", Nothing), ("is", Nothing), ("a", Nothing), ("test", Just 3)].

Я попытался выполнить эту последнюю стадию, используя (неполный) список понимание:

[(x, y) | x <- template, y <- l] 

(Очевидно, что это отсутствует этап, на котором пустые записи будут заменены Nothing с, и работает в предположении, что вход имеет тип [(String, Maybe Int)]).

Что было бы проще семантический способ сделать это?

+0

Рассматривали ли вы с помощью 'Map Струнный Int' в качестве промежуточного представления«список для проверки»? Затем вы можете просто пройти по шаблону, создав новое значение '[(String, Maybe Int)]', заполнив значение «Int», когда оно связано с «String» в фокусе на этой карте. – Jubobs

+0

Думаете, вы могли бы связать меня с документом для этого? Я все еще начинаю с Haskell, и googling просто создает кучу страниц о типах «Map», «String» и «Int», отдельно. Помимо этого, это звучит как многообещающее лидерство. – Jules

+1

https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Strict.html – Fraser

ответ

1

Вы по существу хотите карте функция, в список строк (которые вы называете «шаблон»), то есть функция, которая

  • принимает строку xs,
  • возвращается
    • (xs, Just n), если целое число n связано с xs в вашем «списке для проверки»,
    • (xs, Nothing) в противном случае.

Вот один из возможных подходов:

import Data.List  (lookup) 
import Control.Monad (join) 

consolidate :: [String] -> [(String, Maybe Int)] -> [(String, Maybe Int)] 
consolidate temp l = map (\xs -> (xs, join $ lookup xs l)) temp 

Однако, вы получите быстрый поиск, если вы строите Map держит пары ключ-значение вашего ассоциативного списка («Список для проверки «):

import qualified Data.Map as M 
import Data.Maybe (maybe) 

consolidate :: [String] -> [(String, Maybe Int)] -> [(String, Maybe Int)] 
consolidate temp l = map (\cs -> (cs, M.lookup cs $ fromList' l)) temp 

fromList' :: Ord a => [(a, Maybe b)] -> M.Map a b 
fromList' xs = foldr insertJust M.empty xs 

insertJust :: Ord a => (a, Maybe b) -> M.Map a b -> M.Map a b 
insertJust (xs, maybeVal) mp = maybe mp (\n -> M.insert xs n mp) maybeVal 

В GHCi:

λ> let myTemplate = ["hello", "world", "this", "is", "a", "test"] 
λ> let myList = [("hello", Just 1), ("world", Just 2), ("test", Just 3)] 
λ> consolidate myTemplate myList 
[("hello",Just 1),("world",Just 2),("this",Nothing),("is",Nothing),("a",Nothing),("test",Just 3)] 
Смежные вопросы