#haskell #recursion
Вопрос:
getNames 'A' [('A', "Smith"), ('J', "Brown")] -> ["A.Smith", "A.Brown"]
Я пытаюсь добавить только символ символа к каждому строковому элементу в списке. Мой код:
addForEvery :: Char -> [String] -> [String]
addForEvery a (x:xs) = [a] x : addForEvery a xs
print(addForEvery 'a' ["fa"])
Но я получаю следующую ошибку:
jdoodle.hs:6:32: error:
• Couldn't match type ‘[Char]’ with ‘Char’
Expected type: [Char]
Actual type: [String]
• In the second argument of ‘( )’, namely ‘x : addForEvery a xs’
In the expression: [a] x : addForEvery a xs
In the expression: [[a] x : addForEvery a xs]
|
6 | addForEvery a (x:xs) = [[a] x : addForEvery a xs]
| ^^^^^^^^^^^^^^^^^^^^
Комментарии:
1. В вашем примере, как это
"Smith"
превращается в"Taylor"
?2. Подпись уже противоречива: в вашем примере вторым аргументом является список пар, но в вашей подписи
addForEvery :: Char -> [String] -> [String]
вторым аргументом является список строк.
Ответ №1:
Сделал это!
getNames :: Char -> [(Char, String)] -> [String]
getNames a [] = []
getNames a ((z, b):xs) = ([a] ['.'] b) : getNames a xs
Комментарии:
1. Или
(a : '.' : b)
вместо[a] ['.'] b
Ответ №2:
Проблема в том, что [a] x : addForEvery a xs
это интерпретируется как [a] (x : addForEvery a xs)
. Это не имеет особого смысла, поскольку [a]
String
оно ожидает x : addForEvery a xs
, что это a , но это список String
s .
Вы можете использовать map :: (a -> b) -> [a] -> [b]
для применения одной и той же функции ко всем элементам в списке. Таким образом, мы можем реализовать это как:
getNames :: [(Char, String)] -> [String]
getNames = map toFullName
where toFullName fn ln = fn : '.' : ln