相当于标题所说的内容。我有一个整数列表,如下所示:[1,2,3]。我想把它改成整数123.我的第一个想法是concat但是这不起作用,因为它是错误的类型,我尝试了各种各样的东西,但通常我最终返回相同的列表。非常感谢任何帮助。
此外我找到了一种方法来打印正确的东西(putStr),除了我希望类型为Integer而putStr不这样做。
答案 0 :(得分:23)
您可以使用foldl
来组合列表的所有元素:
fromDigits = foldl addDigit 0
where addDigit num d = 10*num + d
addDigit
函数由foldl
调用,从最左边开始,一个接一个地添加数字。
*Main> fromDigits [1,2,3]
123
修改强>
foldl
从左到右遍历列表,添加元素以累积一些值。
foldl
的第二个参数,在这种情况下为0
,是该过程的起始值。在第一步中,通过调用1
将该起始值与列表的第一个元素addDigit 0 1
结合起来。这导致10 * 0 + 1 = 1.在下一步中,将此1与列表的第二个元素组合,addDigit 1 2
,得到10 * 1 + 2 = 12.然后将其与第三个组合列表的元素,addDigit 12 3
,导致10 * 12 + 3 = 123。
毫无意义地乘以零只是第一步,在接下来的步骤中,实际上需要乘法来将新数字添加到累计数字的“结尾”。
答案 1 :(得分:11)
您可以concat
数字的字符串表示形式,然后read
返回,如下所示:
joiner :: [Integer] -> Integer
joiner = read . concatMap show
答案 2 :(得分:3)
这对我来说非常好。
read (concat (map show (x:xs))) :: Int
函数如何读取:
第1步 - 将列表中的每个int转换为字符串
(map show (x:xs))
第2步 - 将每个字符串组合在一起
(concat (step 1))
第3步 - 读取字符串作为int的类型
read (step 2) :: Int
答案 3 :(得分:2)
答案 4 :(得分:1)
另一个想法是说:最后一位数为1,倒数第二位数为10,前一位数为100,等等。因此,要将数字列表转换为数字,您需要将其反转(以便从后面开始),将数字与相应的10的幂相乘,并将结果相加。
要反转列表,请使用reverse
来获取10的幂,您可以使用iterate (*10) 1
(在GHCi或Hugs中尝试!),将两个列表的相应数字相乘{{1并将所有内容添加到一起,使用zipWith (*)
- 知道一些库函数真的很有用!将这些位放在一起,就得到了
sum
评估示例:
fromDigits xs = sum (zipWith (*) (reverse xs) (iterate (*10) 1))
但是,这个解决方案比fromDigits [1,2,3,4]
==> sum (zipWith (*) (reverse [1,2,3,4]) [1,10,100,1000, ....]
==> sum (zipWith (*) [4,3,2,1] [1,10,100,1000, ....])
==> sum [4 * 1, 3 * 10, 2 * 100, 1 * 1000]
==> 4 + 30 + 200 + 1000
==> 1234
的解决方案慢,因为调用了foldl
并且因为你正在构建那些10的幂而只是再次直接使用它们。从好的方面来说,这种建立数字的方式更接近人们通常的想法(至少我这样做!),而reverse
- 解决方案本质上使用Horner's rule。
答案 5 :(得分:0)
至于如何打印数字,而不是
putStr n
试试
putStr (show n)
原因是putStr
只能打印字符串。所以你需要在传入之前将数字转换为字符串。
您可能还想尝试Prelude的print
功能。这个可以打印任何“可显示的”(类Show
的任何实例),而不仅仅是字符串。但请注意,print n
(大致)与putStrLn (show n)
相对应,而不是putStr (show n)
。
答案 6 :(得分:0)
join :: Integral a => [a] -> a
join [x] = x
join (x:xs) = (x * (10 ^ long)) + join(xs)
where long = length(x:xs)
我们可以定义一个名为join
的函数,给定一个整数列表,它可以返回另一个整数。我们正在使用递归将给定列表的标题与列表的其余部分分开,并使用模式匹配来定义边缘条件,以便递归可以结束。
答案 7 :(得分:-2)
我不是Haskell的专家,但这是我能想到解决这个问题的最简单方法,不涉及任何其他外部函数。
ConcatDigits :: [Int] -> Int
ConcatDigits [] = 0
ConcatDigits xs = ConcatReversed (ReverseDigits xs) 1
ReverseDigits :: [Int] -> [Int]
ReverseDigits [] = []
ReverseDigits (x:xs) = (ReverseDigits xs) : x
ConcatReversed :: [Int] -> Int -> Int
ConcatReversed [] d = 0
ConcatReversed (x:xs) d = (x*d) + ConcatReversed xs (d*10)
如您所见,我假设您正在尝试连接数字列表。如果这不是你的情况,我很确定这不会奏效。 :(
在我的解决方案中,首先我定义了一个名为ReverseDigits的函数,它反转了原始列表。例如[1,2,3]至[3,2,1]
之后,我使用一个ConcatReversed函数,它取一个数字列表和数字d,这是列表位置第一个数字的十次幂的结果。如果列表为空,则返回0,如果不是,则返回列表中第一个数字d,加上调用ConcatReversed传递列表的其余部分,d次返回10。
希望代码能说明问题,因为我认为我糟糕的英语解释并不是很有帮助。