簡體   English   中英

在Haskell中反轉二進制數

[英]Reversing binary numbers in Haskell

我已經為二進制數定義了數據類型,如下所示

data Bin = Nil | O Bin | I Bin 
           deriving (Show, Eq)

我想定義一個函數reverse :: Bin -> Bin這樣當我給出輸入之類的時候

reverse (I (O (I (I Nil))))我應該得到外面的I (I (O (I Nil)))這意味着反轉作為輸入,任何身體請給我提示我怎么能這樣做?

你為什么這樣做? 為什么不是這樣的:

data Bit = I | O
newtype Bin = List Bit

然后你可以直接使用Prelude的反向操作......

編輯 Prelude函數的簡單替換:

reverse x = rev x []
  where
    rev [] a = a
    rev (x:xs) a = rev xs (x:a)

收益率:

reverse x = rev x Nil
  where
    rev Nil a = a
    rev (I xs) a = rev xs (I a)
    rev (O xs) a = rev xs (O a)

問題是,你的類型與列表類型非常相似:

data List a = a : (List a) | []

因此List例程的邏輯直接應用於您的類型。

data Bin = Nil | O Bin | I Bin deriving (Show, Eq)
reverse :: Bin -> Bin
reverse x = rev Nil x
    where
        rev a Nil = a
        rev a ( O b ) = rev ( O a ) b
        rev a ( I b ) = rev ( I a ) b
binToList Nil = []
binToList (O a) = False : binToList a
binToList (I a) = True : binToList a

listToBin [] = Nil
listToBin (False : xs) = O (listToBin xs)
listToBin (True : xs) = I (listToBin xs)

reverseBin = listToBin . reverse . binToList

GHC的List模塊在列表中定義了reverse函數,如下所示:

reverse l =  rev l []
  where
    rev []     a = a
    rev (x:xs) a = rev xs (x:a)

輔助函數rev使用其第二個元素作為累加器,將反轉部分存儲到當前位置。 在每個步驟中,剩余輸入列表的第一個元素被添加到傳遞給遞歸函數調用的累加器的頭部。

可以將相同的原理應用於二進制數類型以反轉數字的順序。

看起來奇怪的是你要定義一個列表類型和一個比特類型。 我想我會重用基礎庫列表類型[] ,並將元素設置為您的位類型,如上面的Aidan所示。

這是一個可能的解決方案:

reverseBin :: Bin -> Bin 
reverseBin b = revBin b Nil
            where revBin Nil acc   = acc
                  revBin (I b) acc = revBin b (I acc)
                  revBin (O b) acc = revBin b (O acc)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM