0

Haskell 新手:

嗨,似乎无法弄清楚这一点。

我想要做的是拿一个字符串,把它变成一个 [Int] (用 map ord)

更改一些满足某些要求的数字(在本例中为 x mod3 == 0)。

之后我想把不变的数字变回char,改变的数字仍然是数字。再次将其组合成一个字符串..

这是我的问题:

*Main> fromStringToList "hihello"
[104,105,104,101,108,108,111]
*Main> changeB3 [104,105,104,101,108,108,111]
"'h'210'h''e'216216222"

我想要的是:

"h210he216216222"

我一直在弄清楚如何使用 show 和 map 来让它在没有来自 Char 的 '_' 的情况下工作。谢谢。

我的代码:

import Data.Char

fromStringToList :: String -> [Int]
fromStringToList "" = []
fromStringToList myString = map ord myString

{-
    changeB3
    PRE: True
    POST: every Int that can be divided by 3 is multiplied by 2 and
kept as int, otherwise transformed to char

-}
changeB3 :: [Int] -> String
changeB3 [] = ""
changeB3 (x:xs)
          | x `mod ` 3 == 0 = show map (x * 2 ) ++ changeB3 xs
          |otherwise = map chr x ++ changeB3 xs
4

1 回答 1

2

我会评论你的代码。

fromStringToList :: String -> [Int]
fromStringToList "" = []
fromStringToList myString = map ord myString

第二行是多余的:当myString为空时,无论如何都map返回。[]你应该删除它。

changeB3 :: [Int] -> String
changeB3 [] = ""
changeB3 (x:xs)
          | x `mod ` 3 == 0 = show map (x * 2 ) ++ changeB3 xs
          |otherwise = map chr x ++ changeB3 xs

您似乎在这里感到困惑。您使用递归函数,但想使用map. 您使用递归或map此处,而不是两者。

假设你想使用map,你应该从定义如何处理单个Int.

changeB3Single :: Int -> String
changeB3Single x | x `mod` 3 == 0 = ...
                 | otherwise      = ...

然后你map在整个列表中。第一次尝试可能是

changeB3 :: [Int] -> String
changeB3 xs = map changeB3Single xs  -- type error!

但这不起作用,因为map这里返回的是字符串列表,而不是单个字符串。我们只需要将它们连接起来。

changeB3 xs = concat (map changeB3Single xs)

事实上,concat (map ...)它是如此普遍,以至于它在库中有自己的功能:

changeB3 xs = concatMap changeB3Single xs

(可以使这一点变得免费,但没有必要——尤其是对于初学者而言。)

于 2016-11-22T14:00:58.980 回答