在 Haskell 中以非等宽块拆分列表
Splitting a list in non-equal width chunks in Haskell
我正在尝试做类似 Haskell 中的事情:
mkList start end nb_chunck will output [start, boun1, bound2, bound3 ..., end]
但是我不想将列表分成等大小的块,而是遵循对数刻度。
我想在 Haskell 中转换的 C 算法在这里可用:
我真的不知道该怎么做。
以下是我到目前为止所做的尝试:
mkList :: Int -> Int -> Int -> Int -> Int -> [Int]
mkList _ _ _ _ 7 = []
mkList lower upper start end n = [lower, ((fromIntegral (log(2 + (fromIntegral n :: Int)) )+start) * scale)] ++ (mkList (fromIntegral(((fromIntegral (log(2 + (fromIntegral n :: Int)) )+start) * scale)+1) :: Int) ((fromIntegral (log(2 + (fromIntegral (n) :: Int)) )+start) * scale) (start) end (fromIntegral (n+1) :: Int)) where
scale = (end - start) `quot` floor(log(1 + (6)))
但是,我无法验证这段代码,因为当我编译时,会弹出错误消息:
haskell_par3.hs:71:58:
No instance for (Floating Int) arising from a use of `log'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `fromIntegral', namely
`(log (2 + (fromIntegral n :: Int)))'
In the first argument of `(+)', namely
`fromIntegral (log (2 + (fromIntegral n :: Int)))'
In the first argument of `(*)', namely
`(fromIntegral (log (2 + (fromIntegral n :: Int))) + start)'
ghc -cpp: /usr/hs/ghc/7.6.3/bin/ghc failure (return code=1)
我曾尝试在不同的地方使用 fromIntegral
但它没有帮助,正如在 Whosebug 上的其他已回答问题中看到的那样。
所以我要问两件事:
- 关于如何修复这些编译错误,您是否有确切的想法? (我知道这与
fromIntegral
有关,但我无法摆脱这个错误)。
- 更重要的是:您认为这段代码可以实现我想要做的事情吗?如果没有,您有什么建议吗?
您可以像这样创建对数刻度间隔
scale k n = map (floor . (*k) . (/(log n)) . log) [1..n]
例如
scale 100 9
[0,31,50,63,73,81,88,94,100]
并使用索引按 start/end 个索引对数组进行分区。
您可以将输出转换为 [Int],因为 floor 将其转换为 Integral 类型
Prelude> scale 10 3 :: [Int]
[0,6,10]
Prelude> :t it
it :: [Int]
我正在尝试做类似 Haskell 中的事情:
mkList start end nb_chunck will output [start, boun1, bound2, bound3 ..., end]
但是我不想将列表分成等大小的块,而是遵循对数刻度。
我想在 Haskell 中转换的 C 算法在这里可用:
我真的不知道该怎么做。
以下是我到目前为止所做的尝试:
mkList :: Int -> Int -> Int -> Int -> Int -> [Int]
mkList _ _ _ _ 7 = []
mkList lower upper start end n = [lower, ((fromIntegral (log(2 + (fromIntegral n :: Int)) )+start) * scale)] ++ (mkList (fromIntegral(((fromIntegral (log(2 + (fromIntegral n :: Int)) )+start) * scale)+1) :: Int) ((fromIntegral (log(2 + (fromIntegral (n) :: Int)) )+start) * scale) (start) end (fromIntegral (n+1) :: Int)) where
scale = (end - start) `quot` floor(log(1 + (6)))
但是,我无法验证这段代码,因为当我编译时,会弹出错误消息:
haskell_par3.hs:71:58:
No instance for (Floating Int) arising from a use of `log'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `fromIntegral', namely
`(log (2 + (fromIntegral n :: Int)))'
In the first argument of `(+)', namely
`fromIntegral (log (2 + (fromIntegral n :: Int)))'
In the first argument of `(*)', namely
`(fromIntegral (log (2 + (fromIntegral n :: Int))) + start)'
ghc -cpp: /usr/hs/ghc/7.6.3/bin/ghc failure (return code=1)
我曾尝试在不同的地方使用 fromIntegral
但它没有帮助,正如在 Whosebug 上的其他已回答问题中看到的那样。
所以我要问两件事:
- 关于如何修复这些编译错误,您是否有确切的想法? (我知道这与
fromIntegral
有关,但我无法摆脱这个错误)。 - 更重要的是:您认为这段代码可以实现我想要做的事情吗?如果没有,您有什么建议吗?
您可以像这样创建对数刻度间隔
scale k n = map (floor . (*k) . (/(log n)) . log) [1..n]
例如
scale 100 9
[0,31,50,63,73,81,88,94,100]
并使用索引按 start/end 个索引对数组进行分区。
您可以将输出转换为 [Int],因为 floor 将其转换为 Integral 类型
Prelude> scale 10 3 :: [Int]
[0,6,10]
Prelude> :t it
it :: [Int]