为什么映射读取显示(整数)不能分隔整数字符串中的每个值?

问题描述 投票:0回答:1

我正在尝试学习如何将一个包含多个数字的整数分成

[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]
或其他什么?

haskell functional-programming
1个回答
0
投票

问题在于

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
情况,因为它只是更一般情况的特殊情况。

© www.soinside.com 2019 - 2024. All rights reserved.