Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Haskell将字符串转换为二进制数_String_Haskell_Functional Programming_Binary - Fatal编程技术网

String 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] 将十进制数转换为其等效的二进

我需要在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]
将十进制数转换为其等效的二进制数。我不知道如何将第二个函数应用于列表中的每个元素,以便将每个字符转换为二进制的等效字符。我尝试使用
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/1
Int
s列表,我们想把它们粘在一起,形成一个函数,将
字符串
转换为0/1
Int
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