我是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.
答案 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)
进行了重构。
答案 2 :(得分:1)
另请查看showIntAtBase
的{{1}}。以下是来源:http://hackage.haskell.org/package/base-4.8.1.0/docs/src/Numeric.html#showIntAtBase