String Haskell将字符串转换为二进制数
我需要在Haskell中将字符串转换为二进制数列表。我已经编写了两个函数来实现这一点,但我不知道如何将它们组合成一个函数。到目前为止我有String Haskell将字符串转换为二进制数,string,haskell,functional-programming,binary,String,Haskell,Functional Programming,Binary,我需要在Haskell中将字符串转换为二进制数列表。我已经编写了两个函数来实现这一点,但我不知道如何将它们组合成一个函数。到目前为止我有 dec[]=[] dec(x:xs) = ord(x): dec xs 将列表中的每个字符转换为十进制数。下一个函数 bin 0 = [0] bin n| n `mod` 2 == 1 = bin (n `div` 2) ++ [1] | n `mod` 2 == 0 = bin (n `div` 2) ++ [0] 将十进制数转换为其等效的二进
dec[]=[]
dec(x:xs) = ord(x): dec xs
将列表中的每个字符转换为十进制数。下一个函数
bin 0 = [0]
bin n| n `mod` 2 == 1 = bin (n `div` 2) ++ [1]
| n `mod` 2 == 0 = bin (n `div` 2) ++ [0]
将十进制数转换为其等效的二进制数。我不知道如何将第二个函数应用于列表中的每个元素,以便将每个字符转换为二进制的等效字符。我尝试使用where
子句:
式中n=dec(x:xs)=ord(x):dec-xs
但这是无效的,因为在同一条线上有两个等号。如何实现正确的功能?我们需要的是
String->String
(decimal->binary
)类型的函数。你现在拥有的是
dec :: String -> [Int]
bin :: Int -> [Int] -- use *lowercase*
因此,似乎不可能仅用这两个函数就组成String->String
类型的函数。此外,ord
不是你想要的
*Main> dec "123"
[49,50,51]
*Main> bin 123
[0,1,1,1,1,0,1,1]
根据您现在的情况,可能的解决方案是:
*Main Data.Char> toBinary = map intToDigit . bin . read
*Main Data.Char> toBinary "123"
"01111011"
我猜你的意图可能是
dec::String->Int
,然后是bin。十二月:字符串->[Int]
。您可以遵循类型签名并重试 您可以非常确定,Int
将以二进制形式存储。它只显示为十进制,因为打印时它会转换为十进制。因此,名称dec
是一个误称,该函数将字符串
转换为表示每个字符Unicode值的数字序列。您可以使用映射避免显式递归:
toUnicode :: String -> [Int]
toUnicode = map ord
请注意,此函数使用所谓的无点样式。缺少所需的参数,但在调用者提供时将传递给map
Bin
函数将不会编译,因为它以大写字符开头,使其成为数据构造函数。您应该以小写字符开始命名函数。根据您的示例输出,您希望在二进制表示中使用前导零,因此当值变为零时无法停止转换。您需要继续,直到您转换了所需的位数(看起来是8)。一直附加到列表也是低效的。最好先进行预处理,然后反转结果
toBinary :: Int -> [Int]
toBinary = go 8 [] where
go 0 acc _ = reverse acc
go n acc x = go (n-1) (bit:acc) x' where
(x', bit) = x `divMod` 2
在这里,我们使用一个助手函数,go
,它在建立1和0的列表时,对剩余位数进行计数
因此,现在我们有一个函数将字符串
转换为Int
s列表,还有一个函数将Int
转换为0/1Int
s列表,我们想把它们粘在一起,形成一个函数,将字符串
转换为0/1Int
s列表。如果我们将map
我们的toBinary
函数映射到toUnicode
的结果上,我们将得到一个列表列表,这些列表必须连接起来形成一个列表。这是一种非常常见的模式,因此有一个函数叫做,concatMap
:
stringToBinary :: String -> [Int]
stringToBinary = concatMap toBinary . toUnicode
在这里,我们使用函数组合首先将
toUnicode
应用于字符串
,然后将concatMap
应用于toBinary
结果。你能给出一个你想要的输入和输出的示例(或几个示例)吗?@DanielWagner让我们假设我给函数一个字符串“ab0”,我想要它输出[0,1,1,0,0,0,0,1,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0]请注意,如果包含任何Unicode值大于255的字符,二进制表示的高位将被省略。
toBinary :: Int -> [Int]
toBinary = go 8 [] where
go 0 acc _ = reverse acc
go n acc x = go (n-1) (bit:acc) x' where
(x', bit) = x `divMod` 2