简体   繁体   English

不同类型的两个列表的笛卡尔积(Haskell)

[英]Cartesian product of two lists of different types (Haskell)

I'm (very) new to Haskell and I'm trying to solve what I think is a simple problem: 我(非常)是Haskell的新手,并且试图解决我认为简单的问题:

I want to create a list of the Cartesian product of two lists of different types: eg. 我想创建两个不同类型的列表的笛卡尔积的列表: one contains characters and one contains integers. 一个包含字符,一个包含整数。

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

and the infinite list: 和无限列表:

    [1..]

I'm trying to get an output where each of my letters is suffixed with a number: eg. 我正在尝试获得一个输出,其中我的每个字母都带有数字后缀:例如。

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

I've been attempting this using things I've read online, however I'm struggling. 我一直在尝试使用在线阅读的内容进行尝试,但是我一直在努力。 As I understand it, I want to convert my integer list to a string using 'show'. 据我了解,我想使用“ show”将整数列表转换为字符串。 My code is below: 我的代码如下:

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

Where xs and cs are passed in my function as ['A','B','C'] and [1..] respectively. xs和cs在我的函数中分别以['A','B','C']和[1 ..]传递。

However I receive this error: 但是我收到此错误:

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

I'd really appreciate any ideas as I've been struggling for a while. 我一直很努力,很感谢任何想法。

Thanks 谢谢

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

parses as 解析为

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

Note that here you are calling xs as a function, with show <$> cs as its argument. 请注意,这里您将xs作为函数调用,并且将show <$> cs作为其参数。 That can't be right: xs is a String! 那不可能是正确的: xs是一个字符串!

Since you seem to be trying to program in applicative style, you probably meant to write something of the form 由于您似乎试图以应用程序风格进行编程,因此您可能打算编写某种形式的内容

f <$> a <*> b

In your case, 就你而言

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

So, you meant to write: 所以,你打算写:

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

This is sorta close to what you wanted, but there are a few problems. 这有点接近您想要的内容,但是存在一些问题。 First, its type is [(Char, String)] , where you wanted them joined up as strings. 首先,它的类型是[(Char, String)] ,您希望在其中将它们连接为字符串。 That can be fixed by using (:) instead of (,) . 这可以通过使用(:)代替(,)

Second, since one list is infinite, you need to process that as your "outermost loop" - if it's an inner loop, the fact that it never ends will mean your other loops never progress. 其次,由于一个列表是无限的,因此您需要将其作为“最外层循环”进行处理-如果它是一个内层循环,那么它永无止境的事实将意味着您的其他循环永远不会进行。 When using [] as an Applicative, the "outer loop" is the first thing you map over. 当使用[]作为Applicative时,“外部循环”是映射的第一件事。

So, we might try: 因此,我们可以尝试:

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

Note I've gone back to (,) for a moment to highlight something: 请注意,我已经回到(,)了一段时间以突出显示某些内容:

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

Now we get the pairs you want, but (:) won't work on them anymore because they're in the wrong order. 现在我们得到了想要的对,但是(:)不再适用于它们,因为它们的顺序不正确。 So, you need to use a different function, one like (:) but which takes its arguments in the other order. 因此,您需要使用其他函数,例如(:)但以另一种顺序使用其参数。 Happily, it is easy to produce such a function: it's simply flip (:) : 幸运的是,很容易产生这样的函数:只需flip (:)

Prelude> take 5 $ (flip (:)) <$> (show <$> cs) <*> xs
["A1","B1","C1","A2","B2"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM