我想从特定的一方获得一个数字的所有子编号。
在数字1234的情况下,左侧的子编号为:
1, 12, 123, 1234
我用以下方式实现了它:
tail . inits $ show 1234
这样我就可以[[Char]]格式获得所有子编号。
["1","12","123","1234"]
我尝试将它们转换为Integer,使用以下行。
map read . tail . inits $ show 1234
但是我收到以下错误
[*** Exception: Prelude.read: no parse
我做错了什么?
答案 0 :(得分:3)
因为解释器不知道你想要什么类型
这将有效:
λ> map read . tail . inits $ show 1234 :: [Int]
[1,12,123,1234]
当然你也可以添加一个类型签名(最有可能在你的代码文件中):
subnums :: Int -> [Int]
subnums = map read . tail . inits . show
在ghci:
λ> subnums 1234
[1,12,123,1234]
如果没有show
/ read
subnumbers :: Int -> [Int]
subnumbers 0 = []
subnumbers n =
n : subnumbers (n `div` 10)
你能解决这里的订单问题吗?
答案 1 :(得分:3)
一个好方法是使用展开。虽然折叠(在其他语言中称为 reduce ,累积或聚合)可以处理数字列表(或其他类型的值)计算单个结果值,展开以单个值开始,并根据给定函数将其扩展为值列表。让我们检查一下展开函数的类型:
Data.List.unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
我们看到unfoldr
采用函数(b -> Maybe (a, b)
和起始b
。结果是[a]
。如果函数的计算结果为Just (a, b)
,则a
将附加到结果中,展开将使用新的b
进行递归。如果函数的计算结果为Nothing
,则展开完成。
你展开的功能是:
f :: Integral b => b -> Maybe (b, b)
f x = if x > 0
then Just (x, x `div` 10) -- append x to result; continue with x/10
else Nothing -- x = 0; we're done
现在我们可以在没有任何show
和read
hackery的情况下解决您的问题:
λ> let f = (\x -> if x > 0 then Just (x, x `div` 10) else Nothing)
λ> reverse $ unfoldr f 1234
[1,12,123,1234]
答案 2 :(得分:2)
作为Carsten suggests,您需要指出您想要的类型。这是因为read
在结果类型中是多态的。在编译器知道你想要什么类型之前,它不知道要使用什么解析器!显式类型注释通常是要走的路,但有时您可能会考虑函数
asTypeOf :: a -> a -> a
asTypeOf x _ = x
我在这里看到两种使用asTypeOf
的明显方法:
λ> asTypeOf (map read . tail . inits $ show 1234) ([0] :: [Int])
[1,12,123,1234]
和
λ> map (asTypeOf read length) . tail . inits $ show 1234
[1,12,123,1234]
第一个看起来几乎没有好转,第二个可能对初学者来说有点棘手 - 但它确实有效;)
为什么呢?由于length
的类型为[a] -> Int
,因此结果类型将固定为Int
:
λ> :t (`asTypeOf` length)
(`asTypeOf` length) :: ([a] -> Int) -> [a] -> Int
这正是我们read
请注意length
做什么并不重要 - 只有它的类型很重要 - 任何其他具有兼容签名的功能都会起作用(尽管我现在只能使用length
)
例如:
wantInt :: [a] -> Int
wantInt = undefined
λ> map (asTypeOf read wantInt) . tail . inits $ show 1234
[1,12,123,1234]
答案 3 :(得分:1)
工作清单理解解决方案:
subNums :: Int -> [Int]
subNums num = [read x | let str = show num, let size = length str, n <- [1 .. size], let x = take n str]
λ> subNums 1234
[1,12,123,1234]