[英]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.