добавить символ символа к каждому второму элементу кортежа в списке

#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