Декартово произведение двух списков разных типов (Haskell) - PullRequest
0 голосов
/ 04 апреля 2019

Я (очень) новичок в Haskell и пытаюсь решить простую проблему:

Я хочу создать список декартовых произведений из двух списков разных типов: например. один содержит символы, а другой содержит целые числа.

   ['A','B','C']

и бесконечный список:

    [1..]

Я пытаюсь получить вывод, где каждое из моих писем имеет суффикс с номером: например.

    ["A1", "B1", "C1", "A2", "B2"..]

Я пытался сделать это, используя то, что я прочитал в Интернете, однако я изо всех сил. Насколько я понимаю, я хочу преобразовать мой список целых чисел в строку, используя 'show'. Мой код ниже:

    combinations xs cs = (,) <$> xs (show <$> cs)

Где xs и cs передаются в моей функции как ['A', 'B', 'C'] и [1 ..] соответственно.

Однако я получаю эту ошибку:

   Couldn't match expected type ‘[String] -> [a0]’
              with actual type ‘[Char]’

Я бы очень признателен за любые идеи, поскольку некоторое время боролся.

Спасибо

1 Ответ

3 голосов
/ 04 апреля 2019
(,) <$> xs (show <$> cs)

анализируется как

(,) <$> (xs (show <$> cs))

Обратите внимание, что здесь вы вызываете xs как функцию, с show <$> cs в качестве аргумента.Это не может быть правдой: xs - это строка!

Поскольку вы, похоже, пытаетесь программировать в аппликативном стиле, вы, вероятно, хотели написать что-то в форме

f <$> a <*> b

В вашем случае,

f = (,)
a = xs
b = show <$> cs

Итак, вы хотели написать:

(,) <$> xs <*> (show <$> cs)

Это как бы близко к тому, что вы хотели, но есть несколько проблем.Во-первых, это тип [(Char, String)], где вы хотите, чтобы они были объединены в строки.Это можно исправить, используя (:) вместо (,).

Во-вторых, поскольку один список бесконечен, вам нужно обработать его как «самый внешний цикл» - если это внутренний цикл, то факт, чтоэто никогда не кончится, будет означать, что ваши другие петли никогда не прогрессируют.При использовании [] в качестве Аппликатива, «внешняя петля» - это первое, что вы отображаете.

Итак, мы можем попробовать:

(,) <$> (show <$> cs) <*> xs

Примечание. Я вернулся к(,) на мгновение, чтобы выделить что-то:

Prelude> take 5 $ (,) <$> (show <$> cs) <*> xs
[("1",'A'),("1",'B'),("1",'C'),("2",'A'),("2",'B')]

Теперь мы получаем пары, которые вы хотите, но (:) больше не будет работать с ними, потому что они в неправильном порядке.Итак, вам нужно использовать другую функцию, такую ​​как (:), но которая принимает свои аргументы в другом порядке.К счастью, такую ​​функцию легко создать: просто flip (:):

Prelude> take 5 $ (flip (:)) <$> (show <$> cs) <*> xs
["A1","B1","C1","A2","B2"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...