在通用基础中表示数字

时间:2015-08-21 16:35:59

标签: haskell

我是Haskell的新手,我只是想编写一个简单的函数,它返回在基类z中传递给它的任何数字k的表示形式,该函数也传递给它

到目前为止,该功能完成了应该做的事情,但反之亦然。

rep 0 _ = [0]
rep z k = (mod z k) : rep (floor (fromIntegral z / fromIntegral k) ) k

还有一个(领先但现在尾随0),但现在这不太重要。例如,rep 1 2会产生[1,0],但会产生[0,1]

另一个例子:rep 8 2应该创建[0,1,0,0],这样会很好,但它会创建[0,0,1,0]。我还认为问题是:附加到列表的前面。我宁愿把代码换成:

rep z k =rep (floor (fromIntegral z / fromIntegral k) ) k : (mod z k)

或括号

rep z k =(rep (floor (fromIntegral z / fromIntegral k) ) k) : (mod z k)

但是没有人能够无限制地工作。

Occurs check: cannot construct the infinite type: t ~ [t]
Relevant bindings include
k :: [t] (bound at knaerBasis.hs:3:7)
z :: [t] (bound at knaerBasis.hs:3:5)
rep :: [t] -> [t] -> [t] (bound at knaerBasis.hs:1:1)
In the first argument of ‘(:)’, namely
‘(rep (floor (fromIntegral z / fromIntegral k)) k)’
In the expression:
(rep (floor (fromIntegral z / fromIntegral k)) k) : (mod z k)
Failed, modules loaded: none.

3 个答案:

答案 0 :(得分:4)

rep的类型为rep :: (Integral a) => a -> a -> [a]),但mod z k的类型仅为a。因此你应该写

(rep (floor ...)) ++ [mod z k]

(:)的类型为a -> [a] -> [a],而(++)的类型为[a] -> [a] -> [a]

另一个合理的选择是在结果列表中调用reverse

答案 1 :(得分:3)

最快的解决方法是在结果上应用reverse

rep :: Int -> Int -> [Int]
rep a = reverse . rep' a
    where rep' 0 _ = [0]
          rep' z k = (z `mod` k) : rep' (z `div` k) k

您之前的(floor (fromIntegral z / fromIntegral k) )也已针对等效表达式(div z k)进行了重构。

Live demo

答案 2 :(得分:1)

另请查看showIntAtBase的{​​{1}}。以下是来源:http://hackage.haskell.org/package/base-4.8.1.0/docs/src/Numeric.html#showIntAtBase