我正在尝试学习如何将一个包含多个数字的整数分成
[Integer]
,我之前看过一篇关于此的文章,他们只是使用模 10 运算符一遍又一遍地查找最后一个/余数并分配该数字到 [Int]
的开头,但为什么不能简单地使用 show 函数将数字转换为 String
(我相信它等于 [Char]
),然后将读取函数映射到每个Char
中的 [Char]
获取 [Char]
中每个点的整数值以制作 [Integer]
?
我想象的代码非常像:
deconstructor :: Integer -> [Integer] //(or trying [Char])
deconstructor n
| n < 0 = map read (show (n * (-1)))
| n == 0 = [read "0"] //(This line works)
| otherwise = map read (show n) //(or in [] or with :: [Integer] on the end)
它给出的错误总是类似于:
* Couldn't match type `Char' with `[Char]'
Expected: [String]
Actual: String
只需处理
show n
就可以很好地编译并给出 String
/[Char]
,我理解映射的方式是,它只是对右侧数组的每个索引(在本例中读取)执行左侧操作(在本例中读取)我想象的是一个[Char]
),那么我不太明白的是什么呢? String
是否必须已经分成不同的[String]
或其他什么?
问题在于
read
必须在 String
上运行,而不是在单个 Char
上运行。如果您 read "1234"
,您正在将 read
应用于 String
,一切都很好,但如果您 map read "1234"
,您正在将 read
应用于 (1 :: Char)
,然后是 (2 :: Char)
,依此类推,并且Haskell 不会接受这种类型不匹配。
您可以使用
Char
中的 String
将 singleton
转换为单字符 Data.List
:
import Data.List
... = map (read . singleton) (show n)
或者你可以使用函数
(:[])
,它是一个“部分”,对角色(对于“头”)和空列表:
(对于“尾”)进行cons []
操作。我提到这一点只是因为它在“野外”的 Haskell 代码中非常常见,所以你会经常看到它的使用:
... = map (read . (:[])) (show n)
所以,以下应该有效:
import Data.List (singleton)
deconstructor :: Integer -> [Integer]
deconstructor n
| n < 0 = deconstructor (-n)
| otherwise = map (read . singleton) (show n)
请注意,您实际上并不需要
n == 0
情况,因为它只是更一般情况的特殊情况。