我已经为二进制数定义了数据类型,如下所示
data Bin = Nil | O Bin | I Bin
deriving (Show, Eq)
我想定义一个函数reverse :: Bin -> Bin
,这样当我提供像
reverse (I (O (I (I Nil))))
我应该了解情况
I (I (O (I Nil)))
这意味着作为输入反转,任何身体请告诉我如何做到这一点?
答案 0 :(得分:8)
你为什么这样做?为什么不这样:
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例程的逻辑直接应用于你的类型。
答案 1 :(得分:6)
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
答案 2 :(得分:4)
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
答案 3 :(得分:2)
GHC的List
模块定义了这样的列表上的reverse
函数:
reverse l = rev l []
where
rev [] a = a
rev (x:xs) a = rev xs (x:a)
辅助函数rev
使用其第二个元素作为累加器,将反转部分存储到当前位置。在每一步中,剩余输入列表的第一个元素被添加到累加器的头部,并传递给递归函数调用。
同样的原则可以应用于二进制数字类型以反转数字的顺序。
答案 4 :(得分:1)
奇怪的是,您要定义列表类型和位类型。我想我会重用基础库列表类型[]
,只需将元素设置为您的位类型,如上面Aidan所示。
答案 5 :(得分:0)
这是一个可能的解决方案:
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)