首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将数字列表转换为没有格式设置的字符串

如何将数字列表转换为没有格式设置的字符串
EN

Stack Overflow用户
提问于 2019-06-28 17:36:23
回答 2查看 135关注 0票数 0

到目前为止,这就是我所拥有的:

代码语言:javascript
复制
toStr :: (Num a) => [a] -> String
toStr (x:xs)
    | length xs == 0 = []
    | length xs > 0 = show x : toStr xs

我一直在犯这个错误:

代码语言:javascript
复制
* Couldn't match type `Char' with `[Char]'
  Expected type: [String]
    Actual type: String

我不明白为什么它收到的是焦耳而不是焦耳。提前谢谢。

为了寻求帮助,我要做的是将二进制列表1、0、0、1、1、0转换为类似于"100110“的列表。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-28 20:06:08

理解问题

代码语言:javascript
复制
toStr :: (Num a) => [a] -> String
toStr (x:xs)
    | length xs == 0 = []
    | length xs > 0 = show x          :  toStr xs
                       ^              ^      ^
                    This is a String  |      |
                                      |  This is a String
                                   This is a function of type String -> [String] -> [String]

所以你有:

  • show x,是一个String
  • toStr xs,是一个String
  • 函数:,它需要一个String[String]

toStr xs的分歧是一个字符串,但:认为字符串列表是问题的症结所在。您希望将字符串连接到一个字符串(show x ++ toStr xs)中。

理解下一个问题*

现在你应该有一些其他的问题。首先,您有一个尝试使用Num a => ashow。函数show不是Num的一部分,而是Show类的一部分,因此将Num a =>更改为Show a =>

最后,这段代码不能很好地处理空列表情况:

代码语言:javascript
复制
 toStr (x:xs)
    | length xs == 0 = []

x之后没有注意到什么,这段代码将忽略最后一个值x,并返回空列表。它不处理没有“最后一个元素”并且只有空列表的情况。要处理这个问题,请尝试使用toStr [] = []

把它放在一起

代码语言:javascript
复制
toStr :: (Show a) => [a] -> String
toStr [] = []
toStr (x:xs) = show x ++ toStr xs

其结果是:

代码语言:javascript
复制
> toStr [1,0,0,1,1]
"10011"

成语代码

上面的结果很好,但是编写Haskell时通常不需要手动的原始递归函数。大多数操作是数据上的mapfold的一种类型。在本例中,它是show函数的映射(注意它是如何对每个元素进行show的)和++函数的fold (也称为字符串级联)。

代码语言:javascript
复制
toStr2 xs = foldr (++) "" (map show xs)
-- > toStr2 [1,0,0,1,1]
-- "10011"

即使这样,也可以进一步简化。它是如此普遍,存在着一个特殊的函数concatMap

代码语言:javascript
复制
toStr3 xs = concatMap show xs

(删除函数定义/应用程序的最外层参数--考虑将函数定义为另一个函数而不是它生成的值):

代码语言:javascript
复制
toStr4 = concatMap show

或者,我们可以重新获得原来的动词-年龄折叠和地图。concatMap函数只是fold + map的一种特定类型,可以在列表上工作。还有一个更通用的foldMap,它可以处理任何生成单面体的函数(列表就是这样的结构之一,这意味着String也是这样的,因为它们是字符列表):

代码语言:javascript
复制
toStr5 = foldMap show
票数 3
EN

Stack Overflow用户

发布于 2019-06-28 19:01:15

正如Sergey所提到的,':‘运算符不能使用,因为表达式"show x“返回的字符串不是一个字符。

下面的代码似乎做了您想做的事情:

代码语言:javascript
复制
toStr :: (Num a, Show a) => [a] -> String
toStr (x:xs)
    | null xs         = show x  -- avoid using length because of cost
    | not (null xs)   = (show x) ++ (toStr xs)
toStr [] = ""


main = do
    let ls1 = [ 13, 17, 19, 23 ]
    let st1 = toStr ls1
    let st2 = concatMap show ls1 -- as per melpomene's remark
    putStrLn $ "st1 = " ++ st1
    putStrLn $ "st2 = " ++ st2

另外,当Haskell程序员只想知道list是否为空时,他们通常避免使用length函数。如果你这样做的话,事情会变得非常糟糕,因为我们的潜在的懒惰列表是无限的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56811124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档