我(非常)是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]’
我真的很感激任何想法,因为我已经挣扎了一段时间。
谢谢
(,) <$> xs (show <$> cs)
解析为
(,) <$> (xs (show <$> cs))
请注意,在这里你将xs
称为函数,以show <$> cs
为参数。这不可能是正确的:xs
是一个字符串!
既然你似乎试图以应用风格编程,你可能想要写一些表格
f <$> a <*> b
在你的情况下,
f = (,)
a = xs
b = show <$> cs
所以,你打算写:
(,) <$> xs <*> (show <$> cs)
这有点接近你想要的,但有一些问题。首先,它的类型是[(Char, String)]
,你希望它们作为字符串连接起来。这可以通过使用(:)
而不是(,)
来解决。
其次,由于一个列表是无限的,你需要将它作为你的“最外层循环”处理 - 如果它是一个内循环,它永远不会结束的事实意味着你的其他循环永远不会进展。当使用[]
作为Applicative时,“外环”是你映射的第一个东西。
所以,我们可能会尝试:
(,) <$> (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"]