Haskell十进制到二进制

dis*_*cco 3 binary haskell decimal

我正在尝试构建一个将Decimal(Int)转换为二进制数的函数.不幸的是,除了在java中,不可能在haskell中将int除以2.我对函数式编程很陌生,所以问题可能是微不足道的.到目前为止,我找不到另一个解决这个问题的方法,但这是我的第一次尝试:

 fromDecimal :: Int -> [Int]

fromDecimal 0 = [0]
fromDecimal n = if (mod n 2 == 0) then 
                do

                0:fromDecimal(n/2) 

                else 
                do  
                1:fromDecimal(n/2) 
Run Code Online (Sandbox Code Playgroud)

我在这里得到了一个java实现,我之前做过:

   public void fromDecimal(int decimal){
    for (int i=0;i<values.length;i++){

        if(decimal % 2 = 0)
        values[i]=true ; 
        decimal = decimal/ 2;
        else {values[i]= false;
        }       }
}
Run Code Online (Sandbox Code Playgroud)

希望这有助于找到解决方案!

Wil*_*sem 8

您的解决方案存在一些问题.首先,我建议使用do 在所有的,直到你明白了什么do一样.在这里我们根本不需要do.

不幸的是,除了在java中,不可能在haskell中将int除以2.

它实际上是,但/运算符(实际上是(/)函数)具有类型(/) :: Fractional a => a -> a -> a.一个Int不是Fractional.您可以使用执行整数除法div :: Integral a => a -> a -> a.

那么代码看起来像:

fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = if (mod n 2 == 0) then 0:fromDecimal (div n 2) else 1:fromDecimal (div n 2)
Run Code Online (Sandbox Code Playgroud)

但我们绝对可以让这更优雅.mod n 2只会导致两个结果:01,这些正是我们在(:)运算符左侧使用的结果.

所以我们并不需要使用if- then- else不惜一切:

fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = mod n 2 : fromDecimal (div n 2)
Run Code Online (Sandbox Code Playgroud)

可能这仍然不是你想要的:在这里我们写二进制值,使最后一个元素是最重要的元素.此函数将添加尾部零,这不会产生语义差异(由于该顺序),但它也不优雅.

go如果给定值不为零,我们可以定义一个省略此零的函数,如:

fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = go n
    where go 0 = []
          go k = mod k 2 : go (div k 2)
Run Code Online (Sandbox Code Playgroud)

如果我们想首先写出最重要的位(所以按照与写入十进制数相同的顺序),那么我们必须反转结果.我们可以通过使用累加器来做到这一点:

fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = go n []
    where go 0 r = r
          go k rs = go (div k 2) (mod k 2:rs)
Run Code Online (Sandbox Code Playgroud)