我(非常)是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]’
我一直很努力,很感谢任何想法。
谢谢
答案 0 :(得分:3)
(,) <$> 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"]