例如,如果输入为“12345”,我希望结果为1 * 2 * 3 * 4 * 5 = 120。 我写了以下内容:
import Data.Char
stringProduct :: Int -> [Char] -> Int
stringProduct p [] = p
stringProduct p (n:ns) = stringProduct np ns
where np = p * (digitToInt n)
main =
print $ stringProduct 1 "12345"
为什么我会8.hs:3:1: Parse error in pattern: stringProduct
?
更新:解决了第一个问题。
但如果结果是整数呢?
答案 0 :(得分:4)
第一个问题是您需要在n:ns
模式周围加上括号,否则Haskell会将其解释为stringProduct p n : ns
:
stringProduct :: Integer -> [Char] -> Integer stringProduct p [] = p stringProduct p (n:ns) = stringProduct np ns where np = p * (digitToInt n)
但现在编译器会抱怨类型:
product.hs:4:30:
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: String
Actual type: Char
In the first argument of ‘read’, namely ‘n’
In the second argument of ‘(*)’, namely ‘(read n)’
您可以通过read
[n]
代替n
(将其转换为单字符字符串)来解决此问题:
stringProduct :: Integer -> [Char] -> Integer stringProduct p [] = p stringProduct p (n:ns) = stringProduct np ns where np = p * (read [n])
现在:
*Main> main
120
要回答你的第二个问题,Int
是 - 如@ThomasM.DuBuisson指出的那样 - 至少30位(范围为-2 29 至2 29 -1),但具有固定的精度(例如64位)。但是Integer
具有任意精度:只要您的机器有足够的可用内存(并且操作系统愿意共享它),它将使用该内存来存储整数的整个值。因此,Integer
没有理论上的最大值(事实上当然,如果您的机器包含 - 交换空间 - 例如8 GiB的内存,最大值将类似于2 2 33 ,这不是无限的,尽管它足以满足大多数实际应用。)
以你的程序的两个简短版本为例:
stringProductInteger :: String -> Integer
stringProductInteger = product . map (read . (:[]))
stringProductInt :: String -> Int
stringProductInt = product . map (read . (:[]))
现在,如果我们进行实验:
*Main> stringProductInt "123456789123456781234567213456723456712345678"
3092908213020917760
*Main> stringProductInteger "123456789123456781234567213456723456712345678"
75525861717854650368000000
Int
以64位溢出,因此结果是Integer
但带有包装的结果。例如:
*Main> (2^33) :: Int
8589934592
*Main> (2^64) :: Int
0
*Main> (2^64) :: Integer
18446744073709551616
*Main> (2^63) :: Integer
9223372036854775808
*Main> (2^63) :: Int
-9223372036854775808
答案 1 :(得分:3)
正如@epsilonhalbe提醒我的那样,这要好得多:
stringProduct = product . map digitToInt
您可以使用一些高阶函数来简化此操作:
stringProduct :: String -> Integer
stringProduct s = product $ map read (map (:[]) s)
打破它......
> map (:[]) "123"
["1", "2", "3"]
> map read ["1", "2", "3"] :: [Integer]
[1,2,3]
> product [1,2,3]
6