2014-12-01 2 views
1

У меня есть следующая функция, которая возвращает список из списка пар.Взяв n-й список из списка списков

getprofileMatrix :: Profile -> [[(Char, Int)]] 
getprofileMatrix (Profile profileMatrix _ _ _) = profileMatrix 

То, что я хочу сделать, это создать функцию, которая принимает Profile, в Int и значение Char, а затем смотрит в списке [[(Char, Int)]] и возвращает п-й список (значение Int параметр), который будет выглядеть следующим образом [(Char, Int)], а затем ищет Char в списке кортежей, и если значение параметра Char соответствует, то оно возвращает значение Int этого кортежа.

Для того, чтобы получить значение Int из в [(Char, Int)] список, я построил следующую функцию:

tupleNr :: Char -> [(Char, Int)] -> Int 
tupleNr letter list = head [nr | (ltr, nr) <- list, ltr == letter] 

Эта функция работает, как ожидалось. Моя проблема заключается при попытке извлечь п-й список из [[(Char, Int]], а затем применяя функцию tupleNr к нему:

profileFrequency :: Profile -> Int -> Char -> Int 
profileFrequency p i c = tupleNr c (map (\x -> (x !! i)).(getprofileMatrix p)) 

Но он не работает .. Я не очень понимаю, почему это не сработает. Сначала я вызываю функцию getprofileMatrix, которая возвращает список [[(Char, Int])] из Profilep. После этого он отображает мою лямбда-функцию для извлечения i-го элемента из списка, чтобы получить один список [(Char, Int)]. Я применяю функцию tupleNr, чтобы получить значение Int списка [(Char, Int)]. Я считаю, что это должно работать, но это не так.

я получаю следующее сообщение об ошибке:

Couldn't match expected type ‘[(Char, Int)]’ 
       with actual type ‘a0 -> [b0]’ 
    In the second argument of ‘tupleNr’, namely 
     ‘(map (\ x -> (x !! i)) . (getprofileMatrix p))’ 
    In the expression: 
     tupleNr c (map (\ x -> (x !! i)) . (getprofileMatrix p)) 
    In an equation for ‘profileFrequency’: 
     profileFrequency p i c 
      = tupleNr c (map (\ x -> (x !! i)) . (getprofileMatrix p)) 


    Couldn't match expected type ‘a0 -> [[b0]]’ 
       with actual type ‘[[(Char, Int)]]’ 
    Possible cause: ‘getprofileMatrix’ is applied to too many arguments 
    In the second argument of ‘(.)’, namely ‘(getprofileMatrix p)’ 
    In the second argument of ‘tupleNr’, namely 
     ‘(map (\ x -> (x !! i)) . (getprofileMatrix p))’ 

Извините, если я не был достаточно ясен, но надеюсь, что кто-то может помочь! Благодарю.

ответ

1

Заменить:

profileFrequency :: Profile -> Int -> Char -> Int 
profileFrequency p i c = tupleNr c (map (\x -> (x !! i)).(getprofileMatrix p)) 

с:

profileFrequency :: Profile -> Int -> Char -> Int 
profileFrequency p i c = tupleNr c . map (!! i) . getprofileMatrix $ p 
--         ^1 ^^^^^^2     ^^^3 

Проблемы были:

  1. Функция приложения имеет приоритет над составом, поэтому в tupleNr c (map (\x -> (x !! i)) вы передаете (map (\x -> (x !! i)), которые является функцией, так как «второй аргумент» tupleNr, который принимает вместо этого список. Вместо этого вы должны составить tupleNr c и (map (\x -> (x !! i)).

  2. Не проблема, а map (\x -> (x !! i) эквивалентна map (!! i), поэтому вы можете реорганизовать ее на это. Это та же концепция, что и (+ 1), являющаяся (\i -> i + 1).

  3. В конце концов, вы должны передать p в сложенную функцию (tupleNr c . map (!! i) . getprofileMatrix). Это не то, что вы делаете: (getprofileMatrix p) имеет тип [[(Char, Int)]], который не является типом функции, поэтому вы не можете его скомпоновать. Поэтому вам нужно отложить приложение p после того, как все функции были составлены.

+0

Спасибо за ответ ..!Но я все равно получаю сообщение об ошибке: Не удалось совместить ожидаемый тип 'Int' с фактическим типом 'a0 -> Int' В выражении: tupleNr c. (map (\ x -> (x !! i)). (getprofileMatrix p)) В уравнении для 'profileFrequency': profileFrequency p i c = tupleNr c. (map (\ x -> (x !! i)). (getprofileMatrix p)) – user3043462

+0

@ user3043462 см. редактирование. – Shoe

+0

Wow Большое спасибо за добавленные комментарии! Действительно ценю это! – user3043462

Смежные вопросы